Archives de l’auteur : cezium

Les Vertex Input Layouts

 

nvidia-quadro-graphics-card

Intro  :

Dans le cas basique, et en général, un vertex a pour attribut seulement sa position. Il existe cependant un mécanisme où il est possible de rajouter d’autres attributs comme : une normale, une couleur, des coordonnées de textures, etc… Je vais tenter de vous expliquer ce mécanisme.

Explications :

Avant tout, lors de l’étape de rendu Input Assembler (voir cet article) les données géométriques présentes dans la mémoire vidéo (composées de ces attributs) sont reçues puis traitées par le Vertex Shader.

Dans DirectX 10, la configuration de ces attributs s’opère sur l’initialisation d’une structure appelée D3D10_INPUT_ELEMENT_DESC.

Ici en tant qu’exemple cette structure (appelée dans le jargon anglais « Vertex Input Layout ») s’implémente ainsi :

Elle permet de définir en mémoire vidéo la façon dont sont agencées les vertex.
Remarque : La taille d’un vertex en mémoire équivaut à la taille de cette structure implémentée.

Une structure correspondante est aussi utilisée dans notre programme :

 


 

Voici les variables de cette fameuse structure :

Paramètres :

SemanticName :

Nom de la « sémantique » de la variable.

Une « sémantique » est une chaîne de caractère qui indique dans quel but la variable doit être utilisée.

Ici son rôle est la position donc on met : « POSITION ».
On peut mettre aussi « NORMAL », « COLOR », « TEXCOORD », etc…

SemanticIndex :

C’est un index (un nombre entier) qui désigne le numéro d’un sémantique qui a déjà été déclaré.

Par exemple, si on déclare deux textures avec sémantique « TEXTURE », on mettra comme SemanticIndex pour le premier champ « 0 » et pour le deuxième champ « 1 ».

Format :

Le format définit le type de données qui sera utilisé pour cet élément.

Par exemple, pour DXGI_FORMAT_R32G32B32_FLOAT : il s’agit d’un attribut avec comme type un flottant et 8 octets alloués par couleur.

InputSlot :

Dans l’étape Input Assembler on peut définir jusqu’à 16 Vertex buffer qui peuvent être utilisés par la carte graphique avant d’être envoyés au Vertex Shader.

Ici on spécifie quel Vertex buffer doit être utilisé par cet attribut.

AlignedByteOffset :

Ce champ dit à la carte graphique quel l’emplacement mémoire pour commencer à aller chercher les données pour cet attribut.
Indiquez D3D10_APPEND_ALIGNED_ELEMENT pour que cet emplacement soit défini de manière automatique.

InputSlotClass :

Cet attribut est utilisé pour gérer l’Instancing. Voir cet article.

InstanceDataStepRate :

Cet attribut est utilisé pour gérer l’Instancing. Voir cet article.

Au final on peut créer cette composition de vertex par le biais de cette méthode : ID3D10Device::CreateInputLayout.

 


 

 

Résumé :

La déclaration d’une structure / composition de vertex permet à la carte graphique de regrouper les informations utiles concernant les vertex en mémoire vidéo avant d’être traités et envoyés au Vertex Shader.

Références :

– http://msdn.developpez.com/direct3d/10/tutoriels/base/

– https://msdn.microsoft.com/en-us/library/windows/desktop/bb205316%28v=vs.85%29.aspx

– https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647%28v=vs.85%29.aspx

Introduction à DirectX 10 – Texturing – partie 3

directx9c

Intro :

Dans cette troisième partie, nous allons apprendre comment ajouter une texture à un petit cube auto généré.

Prérequis :

Avoir suivi la deuxième partie de ce tutoriel.

Troisième partie :

Afficher un petit cube avec une texture appliquée dessus.

Explications :

Dans ce tutoriel nous allons utiliser cette structure de vertex :

La deuxième variable indique que l’on va utiliser les coordonnées de la texture appliqués au cube.

Rajoutez dans votre fichier D3D10Renderer.h :

 

Voici le fichier effet HLSL utilisé – partie3.fx :

 

Dans le fichier D3D10Renderer.cpp à la fonction Initialize(bool bFullScreen) :

Voir cet article si vous ne comprenez pas à quoi sert les matrices World, View et Projection.

On définit la nouvelle structure d’un vertex :

On définit les informations de vertex et index buffers d’un cube :

Voir cet article si vous ne comprenez pas à quoi sert les vertex buffer et index buffer.

On implémente les vertex et index buffers :

 

On charge la texture qui sera utilisée :

 

On initialise les matrices et la texture :

 

Résumé :

Au final nous avons affiché un petit cube texturé.

partie3

Voici l’archive du code complet pour cette partie :  DirectX 10 Tutoriel – Partie 3.zip

Introduction à DirectX 10 – Rendu basique – partie 2

directx9c

Intro :

Dans cette deuxième partie, nous allons utiliser un shader basique pour afficher un triangle et afficher du texte à l’écran.

Prérequis :

Avoir suivi la première partie de ce tutoriel.
Savoir le fonctionnement d’un shader HLSL : pour cela il faut suivre le tutoriel sur le HLSL.

Deuxième partie :

Afficher un triangle et du texte à l’écran.

Explications :

Nous allons utiliser ce programme shader nommé Partie2.fx :

[code language= »c »]

//———————————————————-
// Partie2.fx
//———————————————————-

struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR0;
};

//———————————————————-
// Vertex Shader
//———————————————————-
VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR )
{
    VS_OUTPUT output = (VS_OUTPUT)0;
    
    output.Pos = Pos;
    output.Color = Color;
    
    return output;    
}

//———————————————————-
// Pixel Shader
//———————————————————-
float4 PS( VS_OUTPUT input ) : SV_Target
{
    return input.Color;
}

//———————————————————-
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}

[/cpp]

Si vous ne comprenez ce bout de code, voir l’article sur le HLSL.

Pensez à mettre ce fichier dans le répertoire de votre programme ! Vous aurez une erreur sinon.

Nous allons afficher un triangle à l’écran. Pour cela il faut que DirectX comprenne comment
sont agencés les vertices dans la mémoire vidéo.

Donc ici on déclare que toutes les vertices utilisées sont composées d’une variable position et d’une variable couleur. Cette structure suivante est utilisée par notre application.

Et voilà un schéma des données vertices. Cette structure suivante est utilisée par DirectX.
Voir cet article pour mieux comprendre le mécanisme de cette structure.

 

On rajoute à la fonction Initialize du fichier D3D10Renderer.cpp donné dans la partie 1
du tutoriel :

 

La fonction de rendu va afficher un triangle et un texte comme convenu :

N’oubliez pas d’ajouter dans votre fichier System.h :

Résumé :

Au final nous avons affiché un triangle multi-colorisé et affiché un petit texte :

triangle

Voici l’archive du code complet pour cette partie : DirectX 10 Tutoriel – Partie 2.zip

Index buffer et Vertex buffer

AMD_6990

Intro :

Les notions d’Index buffer et de Vertex buffer sont fondamentales dans la compréhension des étapes de rendu 3D de modèles / meshes. Ils sont appelés sommets et d’indices en français.

Prérequis :

– Aucun

Vertex :

D’abord, qu’est-ce qu’un vertex ?

On peut imaginer un vertex comme un simple point dans un espace 3D. Ce sont ces vertex qui nous permettront de construire les primitives de base (points, lignes, triangles). Et c’est ces primitives nous permettrons de construire des modèles / objets dans le rendu 3D.

Index / Indice :

Qu’est-ce qu’un index (indice) ? Il faut noter que ce sont juste des nombres que l’on va utiliser par groupe de 3 pour représenter l’ordre d’utilisation d’un triangle.

Autrement dit, c’est un triplet d’index qui sert à indiquer à la carte graphique dans quel ordre sont utilisés les vertex affichés par celle-ci. Ces index peuvent servir à réutiliser les vertices précédemment déclarés.

Vertex buffer :

Un Vertex buffer est simplement une interface stockant les informations sur les vertices d’un modèle du jeu. C’est un tableau situé dans la mémoire de la carte graphique.

On peut stocker dans un vertex buffer des informations : comme la position, les vecteurs normales, les coordonnées d’une texture ou encore même la couleur, voir même n’importe quoi…

Index buffer :

De même que le Vertex buffer,  c’est une interface qui stocke les indices présents dans un tableau contigu.


Déclaration de vertex :

Pour que la carte graphique comprenne comment sont agencées les données d’un vertex buffer, il faut déclarer une structure correspondante. On appel cela une « déclaration de vertex ».

 


 

Avant tout il faut définir une structure correspondante et représentative du type de Vertex :


Code C++ d’implémentation d’un Vertex Buffer statique :


Code C++ d’implémentation d’un Index Buffer :


Résumé :

Pour afficher un modèle dans un rendu 3D on a besoin de définir comment il est représenté : c’est-à-dire par deux tableaux d’informations de Vertex et d’Indices et une déclaration de vertex.

 

Introduction au moteur 3D Irrlicht – partie 1

I073

 

Intro :

Irrlicht 3D est un moteur 3D gratuit et open-source écrit en C++.
Son utilisation est facilité par le petit nombre de méthodes (fonctions) qu’il possède par rapport à Ogre3D qui quant à lui comporte beaucoup plus de fonctions. Irrlicht 3D est donc plutôt simple à utiliser.

Il gère aussi bien les APIs DirectX que OpenGL. Il peut être aussi utilisé sur Linux, Windows et OS X.

Version d’Irrlicht 3D utilisée : 1.8.1

Prérequis :

– Savoir lire les rudiments d’un programme C++ (pointeur, classe, etc…)
– Savoir configurer Visual Studio C++ Express (voir cet article)

Explications :

Il vous faut comprendre comment configurer les répertoires de dépendance dans Visual C++.

Télécharger Irrlicht :

http://irrlicht.sourceforge.net/downloads.html

Ce qu’il y a dans le repertoire extrait :

bin : les bibliothèques dynamiques et les binaires des exemples du SDK

include : les principaux headers du code source

lib : les bibliothèques statiques

Ce qu’il faut faire :

Dans le répertoire bin extrait : il vous suffit de choisir le dossier correspondant à votre configuration et de copier le fichier .dll quelque part.
Vous devrez le mettre dans le même dossier que vos fichiers exécutables (.exe) pour que ceux-ci fonctionnent.

Il faut configurer votre IDE (en l’occurence Visual Studio C++)
en paramétrant les dossiers include / et lib (suivre ce tutoriel pour le configurer [config_vc++]

Mettre dans votre fichier .cpp principal :

 


 

Exemple complet :

 


Fonction createDevice (…) :

 

Explication du bout de code :

Les arguments passés en paramètre sont dans l’ordre :

– device  : c’est un pointeur sur l’objet returné par irr:createDevice(…)

– deviceType : désigne l’API graphique avec laquelle va s’interfacer Irrlicht. Nous utiliserons OpenGL tout au long du tutoriel, mais on peut aussi choisir Direct3D par exemple en mettant la valeur EDT_DIRECT3D9.

– windowSize : la taille de la fenêtre. Tout est dit ! Avec le code indiqué plus haut, on crée une
fenêtre de 800 par 600 pixels.

– bits : détermine le nombre de bits par pixels.

– fullscreen : un booléen qui indique si on veut faire du plein écran ou pas. Pour la valeur true l’application
sera en plein écran, et pour false la fenêtre sera de la taille définie plus haut.

– stencilbuffer : un autre booléen qui indique lui si on active le stencil buffer ou pas. Il est actif pour true.

– vsync : toujours un booléen. Celui-ci sert à activer la synchronisation verticale. Pas de mystère, elle est active pour true.

– receiver : permet d’associer un capteur d’événements au device (0 signifie qu’on n’associe rien). Nous verrons de quoi il s’agit dans un prochain chapitre.

Résumé :

Dans cette première partie nous avons appris comment se servir de Irrlicht 3D.

Références :

– http://irrlicht.sourceforge.net/features/
– http://openclassrooms.com/courses/3d-temps-reel-avec-irrlicht
– http://irrlicht.sourceforge.net/docu/example001.html

Une console Quake-like colorisée

quake-like_console

Intro :

Parfois dans un jeu on a besoin de configurer ou de paramétrer le gameplay ou les mécanismes du jeu directement dans le programme.

Prérequis :

– Savoir un peu utiliser DirectX 10

– Savoir lire du C++

Explications :

On peut entrer et exécuter des commandes (toutes très utiles) pour modifier les variables ou les comportements du jeu. On peut aussi par ce biais afficher des informations système ou des informations sur le comportement du jeu.

Nous allons implémenter cette console dans DirectX 10. Mais vous pouvez aussi l’implémenter dans votre propre application à partir du code expliqué.

Cette console présente les fonctionnalités suivantes :

– éléments de texte en couleur
– historique de commande
– commandes basiques
– image de fond
– correction / suppression de caractère de la ligne de commande

Prérequis :

– Savoir lire du C++

– Savoir initialiser DirectX 10

Explications :

Voici le fichier Console.h :

 

Voici le fichier Console.cpp :

Résumé :

Voici le code de cet article : archive.

Les principales étapes de rendu de DirectX 10

Intro :

Le rendu graphique de DirectX 10 consiste en plusieurs étapes.

Prérequis :

Savoir utiliser et implémenter DirectX 10.

Explications :

Voici un schéma qui les résume :

220px-D3D_Pipeline.svg

Les rectangles carrés indiquent que l’étape de rendu ne peut pas être configurée par un script ou programme HLSL.

A l’inverse, les rectangles arrondies indiquent que l’étape de rendu peut être configurée par un script ou programme HLSL.

Voir cet article si vous ne savez ce qu’est le HLSL.

 


 

Étape Input Assembler :

Cette étape prépare les données géométriques à la chaîne de rendu 3D. Les données des Vertex Buffers et des Indexes Buffers sont agencées d’une certaine façon dans la mémoire de la carte graphique et à partir de ceux-ci, l’étape Input Assembler créée les primitives géométriques correspondantes (triangles, lignes, points, etc…) afin de les passer au Vertex Shader.

Étape Vertex Shader :

Cette étape permet de modifier les vertices en entrée. Elle consiste à transformer ces vertices depuis les coordonnées Object-space vers les coordonnées Clip-Space ; c’est-à-dire les coordonnées du modèle d’origine vers les coordonnes du cadre de vue de l’écran 2D.
Elle sert aussi à changer la position des vertex dans le repère 3D. Elle est responsable aussi d’effectuer les animations des modèles / personnages du jeu et permet aussi d’effectuer un rendu basique de lumière (en l’occurence du per-pixel ligthing).

Voir le Lexique si vous ne comprenez pas tous ces termes.

Elle traite un vertex à la fois : c’est-à-dire que cette étape est exécutée en boucle pour chaque vertex.

Les données en sortie de cette étape vers le Vertex shader (qui est en fait une fonction toute simple avec entrée et sortie) peuvent être : les coordonnées des textures, la couleur des vertex, etc…

Étape Geometry Shader :

Cette étape optionnelle permet de modifier complètement la géométrie des modèles / meshes.
Au lieu de recevoir vertex par vertex cette étape reçoit une primitive totalement assemblée (une ligne ou un triangle par exemple) ; de là on peut générer d’autres primitives à la volée. Le Geometry Shader peut ignorer une primitive ou en générer de nouvelles.

Étape Stream-Output Stage :

Génère le flux des primitives géométriques depuis la mémoire vers l’étape Rasterizer.

Étape Rasterizer :

Cette étape permet de rassembler les primitives afin de les envoyer au Pixel Shader. Elle s’occupe aussi de couper les primitives qui dépassent le cadre de vue de l’écran.

Étape Pixel Shader :

Cette étape s’occupe de modifier l’affichage de chaque pixel et pour chacun de ceux-ci elle renvoie une couleur en sortie.

Étape Output Merger :

Cette étape s’occupe quel pixel doit être affichée à l’écran. Les pixels générés sont calculés sur la base du Pixel Shader, du contenu des Render Targerts, du contenu du Depth Buffer et du contenu du Stencil Buffer.

 

Résumé :

Nous avons énuméré toutes les étapes du rendu 3D de DirectX 10.

Références :

– Pipeline Stages (Direct3D 10) – DirectX10 June 2010 SDK Documentation

Introduction à DirectX 10 – Fenêtrage – partie 1

Intro :

Ceci constitue une introduction à la version 10 de DirectX.

DirectX est une interface entre le programmeur et la carte graphique.

Dans cette partie je vais vous apprendre à l’initialiser de manière rudimentaire.

Prérequis :

Savoir programmer en C++.

Première partie :

Création de la fenêtre de rendu.

Explications :

Pensez à configurer les chemins d’accès du SDK de DirectX  dans VC++ ! Si vous ne savez pas comment faire : lire ce tutoriel.

On a besoin d’utiliser une fonction qui boucle à chaque fois que l’application reçoit
un message :


Ensuite créez un fichier System.cpp et un fichier System.h où vous mettrez les fonctions que je vous énoncerai.

Voici le fichier System.h :

Dans le fichier System.cpp. On initialise d’abord une fenêtre Windows ; voici la fonction pour l’initialiser :

 

Toujours dans System.cpp, la fonction pour détruire la fenêtre :

 

La fonction pour initialiser la fenêtre et le Renderer de DirectX 10 :

 

 


 

La fonction WinMain est dans le fichier Main.cpp et est implémentée de cette façon :

 


 

Ensuite créez un fichier D3D10Renderer.cpp et un fichier D3D10Renderer.h où vous mettrez les fonctions que je vous énoncerai.

 

La fonction pour afficher le rendu :

 

Résumé :

Nous avons affiché une fenêtre prête à recevoir le rendu de DirectX.

fenetre

Voici l’archive du code complet pour cette partie : DirectX 10 Tutoriel – Partie 1.zip

Voilà le code et les explications pour initialiser la fenêtre de DirectX 10.
Il reste beaucoup de choses à intégrer pour faire un jeu mais vous saurez au moins comment intégrer DirectX 10.

Références :

– https://takinginitiative.wordpress.com/directx10-tutorials/

– http://www.rastertek.com/tutdx10.html

– DirectX SDK June 2010 Documentation Samples

Classe CommandLineManager pour récupérer les paramètres de votre exécutable

Terminal-icon-shell-linux-unix

Intro :

[utiliser la classe DataParameters]

On peut passer à exécutable des paramètres comme suit : mon_exécutable.exe -param1 arg1 arg2 -param2 arg3

Cette classe va vous permettre de les récupérer vos arguments plus facilement.

Préréquis :

– Savoir lire du C++

– Savoir écrire un programme rudimentaire  en C++

Explications :

Voici le fichier d’en-tête ParametersManager.h :

Voici le fichier .cpp :

 

Utilisation :

On utilise ce bout de code dans la fonction main (int argc, char** argv) :

 

Résumé :

Nous avons présenté une méthode pour analyser vos arguments en ligne de commande.

Utilisation du préprocesseur

224706

Intro :

En C++, avant de compiler le programme, il est possible d’effectuer certaines modifications sur le code source. Le programme effectuant ces modifications s’appelle le préprocesseur. Les commandes destinées au préprocesseur commencent toutes par # en début de ligne.

Prérequis :

Savoir les rudiments du C++.

Inclusion de fichiers sources :

On peut inclure des fichiers .h avec la directive #include :

Cela a pour effet d’inclure le code source du fichier à l’emplacement indiqué.

Directives du préprocesseur :

#define : permet de définir une constante globale :

#ifndef : permet de tester si la variable testée n’est pas définie

#ifdef : permet de tester si la variable testée est définie

Macro prédéfinies :

__DATE__ : date de compilation du fichier source actuel

__FILE__  : nom du fichier source actuel

__LINE__ : numéro de ligne dans le fichier source actuel

__TIME__ : heure de compilation la plus récente du fichier source actuel

__FUNCTION__ : nom de la fonction en cours

_WIN32 : défini si le programme est compilé sous Windows ou non

__VA_ARGS__ : voir cette article

Pragma :

Pour supprimer des warnings que vous jugez inutiles :

Pour spécifier au compilateur que le fichier ne doit être inclu qu’une fois :

Pour spécifier au compilateur de lier une librairie donnée :

 

Résumé :

Nous avons énuméré les principales fonctionnalités du préprocesseur en C++.

Classe DataParameters pour faciliter l’échange d’information entre modules

todo : refaire le stream reset avec une méthode

Intro :

Parfois il est utile de regrouper des paramètres ensemble afin de les échanger entre modules.

Explications :

Voici le fichier DataParameters.h :

Voici le fichier .cpp :

 

Résumé :

Nous avons présenté un objet rassemblant des données pouvant être de différents types.

Avec les flux << et >>  nous avons intégré une technique plus simple pour échanger des données.

Système d’Events pour gérer les événements du jeu (1ère approche)

b7ef9923828960d1a0935b08fb5ac0d2

Intro :

Dans la conception d’un jeu il est très important d’énumérer tous les mécanismes intrinsèques au comportement du jeu, c’est-à-dire des événements du gameplay, du son, de l’interface, du réseau, de la gestion des collisions et de l’IA.

Ceci est une première approche au problème.

J’ai écrit un article sur une deuxième approche plus juste et mieux adaptée.

Ici on parle des événements, nommés aussi Events.

Prérequis :

La compréhension de l’utilisation de la classe DataParameters.

Explications / exemples :

On se sert de deux macros.

Voici des macros permettant de simplifier la définition de vos Events  :

Je vous fournis deux macros : une pour un Event sans paramètres et une autre pour les Events
avec paramètres.

Voici le fichier .h de la classe Event :

Voici le fichier .cpp

On définit les Events comme suit :

Et on implémente les Events comme suit :

Voici le fichier EventManager.h :

Voici le fichier EventManager.cpp

On enregistres les Events comme ci :

 

Résumé :

L’implémentation d’un système d’Event est cruciale dans toute conception de jeu vidéo. Elle permet en effet de modulariser les mécanismes de jeu et rend le code plus élégant et plus facile à comprendre.

Classe BoundingVolumeTrigger pour vos triggers

1

Intro :

Dans un jeu vidéo on doit utiliser beaucoup de bounding boxes pour déclencher certains événements.

Prérequis :

Si vous ne savez pas ce qu’est une Bounding Box : se référer à l’article traitant les Bounding Boxes.
Si vous ne savez pas ce qu’est un Event : se référer à l’article traitant les Events.

Utilisation :

Par exemple lorsque que le joueur entre dans une nouvelle zone, on a besoin de tester deux bounding boxes : celle du joueur et celle du trigger (déclencheur), pour ensuite faire appel à l’événement (Event) associé.

Voici une classe à copier pour implémenter le mécanisme de triggers dans vos jeux.

Dans le fichier .h :

Dans le fichier .cpp :

La variable m_bTriggerDone restreint l’invocation du déclencheur à un seul appel par rencontre
de collision.

Résumé : 

Le Singleton

Intro :

Le Singleton est un patron de conception.

Il est utile lorsque l’on a besoin d’utiliser et d’instancier un seul objet au lieu le passer paramètre après paramètre et fonction par fonction.

En somme il permet d’accéder directement dans tout le programme un objet quelconque (appelé « Singleton »).

Explications / exemples :

Cas sans le Singleton :

Cas avec le Singleton :

On accède directement à l’objet sans avoir à le passer paramètre par paramètre :

Donc  :


Voici le fichier d’en-tête / d’include :

 

Utilisation :

Dans le fichier include : EventManager.h

Dans le fichier cpp : EventManager.cpp

on doit mettre tout en haut de ce fichier :


Exemple d’utilisation :

Astuces et conseils :

warning

1 – N’oubliez surtout pas de créer votre objet avant son utilisation en appelant :

sinon vous obtiendrez un bug de pointeur non initialisé ! (segfault)

2 – Utiliser plusieurs macro #define de la sorte :

on utilise cette macro / raccourcis pour appeler une méthode : EVENT_MANAGER->methode()
cela permet de simplifier l’écriture du code…

Résumé :

Le patron de conception Singleton restreint l’instanciation d’une classe à un seul objet.
Il permet de simplifier l’accès global à un objet (par exemple à une classe TextureManager ou EventManager)

Initialiser rapidement DirectX 10.1 avec DXUT

1342671301_50721

Intro :

DXUT est un framework qui vous permet d’initialiser de manière plus rapide et plus simple DirectX 10 à travers des fonctions toutes prêtes.

Prérequis :

Savoir un peu initialiser DirectX.

Exemples :

Voici un exemple d’utilisation :

On remarque bien que quelques lignes suffisent pour démarrer DirectX 10 avec DXUT.

Vous remarquerez aussi que l’on insère des fonctions en tant que paramètres : ce sont des fonctions callbacks (c’est-à-dire des fonctions qui sont appelées de manière interne par DirectX).

Explications :

Initialisation :

Le premier argument indique à DXUT d’interprêter ou non les arguments passés en ligne de comande :

BasicHLSL.exe -windowed -width:400 -height:300

Le deuxième argument indique à DXUT d’afficher ou non une boite de dialogue s’il une erreur à lieu.

Les deux autres arguments ne sont pas nécessaires pour comprendre.

Curseur de la souris :

Voici l’instruction pour configurer le curseur de souris.

Le premier paramètre indique à DXUT que le curseur doit ou non
être affichée en mode plein écran.

Le premier paramètre indique à DXUT que le curseur doit
être restreint ou non de traverser les bords de la fenêtre en mode plein écran.

Création d’une fenêtre :

Le premier argument spécifie le titre de la fenêtre.

Le deuxième argument spécifie l’handle de la fenêtre (on peut le mettre à NULL).

Le troisième argument spécifie à la fenêtre quelle icone utiliser (on peut le mettre à NULL aussi).

Les deux autres arguments ne sont pas nécessaires pour comprendre.

Création du device :

Le premier argument indique ou non si la fenêtre créée doit être en plein écran ou fenêtrée.

Les deux autres arguments indiquent la résolution (au mieux) de la fenêtre de rendu.

Par ailleurs, après cette instruction, DXUT choisira automatiquement la version de DirectX : D3D9 ou D3D10, selon les capacités du matériel.

Rendu :

Au final l’Instruction pour démarrer la boucle de rendu :


Les fonctions Callbacks :

Maintenant pour utiliser DXUT on doit créer un fichier Callbacks.h où mettrez le code des fonctions nécessaire à DXUT :

 

Vous mettrez toutes les fonctions énumérées ici prochainement dans un fichier DXUTIntroduction.cpp

La première fonction callback :

 

La deuxième fonction callback :

 

La troisième fonction callback :

 

La quatrième fonction callback :

 

La cinquième fonction callback :

 

La sixième fonction callback :

 

La septième fonction callback :

 

La huitième fonction callback :

 

La dernière fonction callback :

 

Résumé :

DXUT vous permet de restreindre d’initialiser de manière laborieuse DirectX 10.
Vous pouvez retrouver le code source de ce petit tutoriel ici.

Références :

Documentation DirectX SDK June 2010

Un système de Process et de ProcessManager

 

WoWScrnShot_082916_183045

Intro :

Dans un jeu vidéo on fait souvent appel à plusieurs sous-systèmes et pour les mettre à jour fréquemment.

On va utiliser deux classes permettant de gérer ces sous systèmes.

class Process : classe de base, on peut la dériver puis redéfinir la méthode VUpdate().
class ProcessManager : gestionnaire d’instances de Process.

Un Process peut être n’importe quoi : il faut juste tout simplement que ce soit un objet qui nécessite d’être mise à jour.

Par exemple on peut l’utiliser pour : le système de script, des collisions, de l’audio, de l’IA, du rendu de certaines entités.

Si on veut mettre le jeu en pause il  suffira de faire appel aux méthodes Pause() et UnPause().

Pour le fichier include Process.h

Dans le fichier Process.cpp :

Maintenant pour le fichier include ProcessManager.h :

Pour le fichier ProcessManager.cpp :


Résumé :

Ces classes vous seront utiles pour implémenter vos propres systèmes / process.

Références :

– Game Coding Complete 4 (code LGPL)

Les vecteurs

vector_2d_coordinates

Intro :

Ceci constitue un petit cours sur les vecteurs que vous avez vus normalement au lycée.

Un vecteur est une entité mathématique qui désigne aussi bien une position qu’une direction dans un repère donné.
Un vecteur peut servir à représenter une force, une position, une vitesse, par exemple la direction à laquelle le joueur regarde, etc…

Dans cet article on notera un vecteur \({v}\) plutôt que \(\vec{v} \).

Prérequis :

– Avoir déjà lu et compris quelques rudiments sur les mathématiques des vecteurs.

Explications :

Un vecteur se note de cette façon : \(v=({x,y,z})\)

Opérations sur les vecteurs :

Obtenir la négation d’un vecteur :

\(-v=-({x,y,z}) = ({-x,-y,-z})\)

 

On peut ajouter deux vecteurs :

\({v + w} = {({v_{x},v_{y},v_{z}}) + ({w_{x},w_{y},w_{z}})} = ({v_{x} + w_{x},v_{y} + w_{y},v_{z} + w_{z}})\)

 

Soustraire deux vecteurs :

\({v – w} = {v + (-w)} = {({v_{x},v_{y},v_{z}}) + ({-w_{x},-w_{y},-w_{z}})} = ({v_{x} – w_{x},v_{y} – w_{y},v_{z} – w_{z}})\)

 

Multiplier un vecteur par un scalaire :

\(\textbf{k}v = ({\textbf{k}v_{x}, \textbf{k}v_{y}, \textbf{k}v_{z}}) \)

 

On peut inverser la direction d’un vecteur dans le même genre :

\({(\textbf{-1})}v = -v = ({-v_{x}, -v_{y}, -v_{z}}) \)

 

On peut calculer la longueur d’un vecteur (en utilisant le théorème de Pythagore) :

\(\|v\| = \sqrt{{v}_x^2+{v}_y^2+{v}_z^2} \)

 

On peut calculer la distance entre deux vecteurs :

\(distance({a}, {b})=\|{b}-{a}\|=\sqrt{({b}_x-{a}_x)^{2}+({b}_y-{a}_y)^{2}+({b}_z-{a}_z)^{2}}\)

 

Normaliser un vecteur (rendre sa longueur de 1 unité) :

\({v}_{norm}=\frac{{v}}{\|{v}\|}\)

 

Il existe aussi deux autres opérations qui sont : le produit scalaire et le produit vectoriel.

L’opération du produit scalaire donne comme résultat un nombre (d’où le nom « scalaire ») :

\({v}\cdot{w}={v}_{x}{w}_{x}+{v}_{y}{w}_{y}+{v}_{z}{w}_{z}\)

 

Il s’exprime aussi avec la fonction cosinus avec comme paramètre l’angle entre les deux vecteurs :

\({v}\cdot{w}=\|{v}\|\|{w}\|\cos(\theta)\)

 

Le produit scalaire est une opération fondamentale dans le calcul des lumières dans le rendu graphique 3D.

On peut trouver l’angle entre les deux vecteurs ainsi :

\(\theta=\arccos\left(\frac{{a}\cdot{b}}{\|{a}\|\|{b}\|}\right)\)

 

La fonction arccos est tout simplement la fonction cos⁻¹ de votre calculatrice.

L’opération du produit vectoriel :

\({w}={u}\times{v} \)

 

Le résultat du produit vectoriel est un vecteur perpendiculaire aux deux vecteurs (u et v) de l’opération ; le sens de ce vecteur dépend de l’ordre des opérandes dans la multiplication.

On le calcul d’après la formule suivante :

\({w}={u}\times{v}=(({u}_{y}{v}_{z}-{u}_{z}{v}_{y}),({u}_{z}{v}_{x}-{u}_{x}{v}_{z}),({u}_{x} {v}_{y}-{u}_{y}{v}_{x})) \)


Résumé :

Nous avons vu la notion de vecteur ; objet mathématique fondamentale dans la réalisation d’un jeu vidéo en 2D ou 3D.

Fonction à nombres variables d’arguments

Intro :

Il peut être utile de passer un nombre indéfini de paramètres à une fonction.

Il faut inclure au minimum un paramètre obligatoire. Ensuite on peut passer un nombre indéfini d’arguments à la fonction.

Exemple  :

Les trois petits points (…) indique au compilateur que la fonction peut prendre plusieurs arguments.

Il faut inclure pour accéder aux fonctions et macros de manipulation des paramètres variables.

On doit indiquer en paramètre le nombre d’arguments passés par cette fonction ! (ici « int n »)

Ici on récupère des variables de type char* (chaine de caractères).

Résumé :

Les fonctions qui peuvent prendre un nombre variable d’arguments ne sont pas toujours utilisées mais peuvent toujours être utiles.

Récupérer les informations du système

Intro :

2000px-Computer-aj_aj_ashton_01.svg

Cette classe va vous permettre de récupérer les informations de votre système d’exploitation, du nom de votre processeur et de sa vitesse, du nombre de mémoire que vous disposez…


Explications :

Dans le fichier ComputerInfo.h :

Dans votre fichier ComputerInfo.cpp :


Résumé :

Cette classe permet d’accéder aux informations de votre système d’exploitation Windows.

 

Macro avec multiple passage d’arguments

Intro :

Parfois il est nécessaire d’utiliser une macro avec nombre variable d’arguments / paramètres

Utilisation :

Ce sont des macros similaires aux fonctions qui contiennent un nombre variable d’arguments.

On peut utiliser une macro avec un nombre variables d’arguments :

Le mot-clé __VA_ARGS__  sert à remplacer les occurences de paramètres dans la fonction appelée.

Résumé :

Les macros avec nombre variable d’arguments peuvent toujours trouver leur utilité même s’il ne sont pas très utilisées.

Références :

https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html