Archives de l’auteur : cezium

Une classe ShaderManager pour gérer vos fichier shaders

AMD_6990

Intro :

Prérequis :

– Savoir utiliser un peu DirectX 10

– Savoir utiliser la classe Singleton. Voir cet article.

– Savoir ce qu’est un fichier shader.

– Savoir utiliser la classe ShaderTechnique.

Explications :

Voici le fichier ShaderManager.h :

 

Voici le fichier ShaderManager.cpp :

 

Résumé :

Voici une classe toute simple qui permettra de rassembler tous vos shaders encapsulés dans une collection std::map.

Une classe Skybox pour afficher un ciel autour de votre caméra – 1ère approche

skybox

Intro :

Pour que votre scène soit réaliste, il peut être utile d’afficher un décor de ciel de grande taille autour de la caméra.

Ceci constitue une première approche à l’affichage d’une Skybox.

Prérequis :

– Savoir utiliser la classe ShaderTechnique. Voir cet article.

– Savoir utiliser la classe MeshSceneNode. Voir cet article.

– Savoir un peu utiliser DirectX 10.

Explications :

Tout d’abord la classe dérivant ShaderTechnique :

 

Voici ensuite le fichier ShaderTechnique_SkyBox.cpp :

 

Voici le fichier SkyBoxSceneNode.h :

 

Voici le fichier SkyBoxSceneNode.cpp :

 

Voici le fichier SkyBox.fx :

 

Résumé :

Nous avons présenté un énorme cube autour de la caméra qui servira de ciel ou de décor.

Une classe MeshSceneNode pour représenter des meshes dans votre scène

mesh node

Intro :

Pour afficher vos entités / mesh dans la scène 3D, je vous présente une classe qui permettra de les initialiser rapidement.

Elle pourra construire facilement du contenu 3D à partir des méthodes suivantes :

 

Prérequis :

– Savoir utiliser la classe SceneNode. Voir cet article.

– Savoir utiliser la classe Renderable. Voir cet article.

– Savoir un peu utiliser DirectX 10

– Comprendre la classe SceneNode

 

Explications :

Voici le fichier MeshSceneNode.h :

 

Resumé :

Nous avons présentée une classe qui permettra d’afficher du contenu 3D dans vos scène d’entités (SceneNode).

Une classe Renderable pour afficher vos contenus 3D

test_remeshing

Intro :

Pour afficher rapidement du contenu 3D, il est laborieux de déclarer à chaque fois les vertex et index buffers, le shader associé, le Vertex Input Layout, la méthode d’affichage, etc…

Cette classe suivante vous permettra de restreindre ces difficultés.

Prérequis :

– Savoir utiliser la classe ShaderTechnique. Voir cet article.

– Savoir un peu utiliser DirectX 10.

Explications :

Voici le fichier Renderable.h :

 

Voici le fichier Renderale.cpp :

 

Résumé :

Cette classe pourra servir à être dérivée pour afficher vos contenus 3D : image, quad de post-effect, rendu 3D, etc..

Différents types de déclarations de vertex pour DirectX 10

nvidia-quadro-graphics-card

Intro :

Dans nos programmes de rendu 3D nous avons besoin d’utiliser différents types de configurations de vertex.

Prérequis :

– Savoir utiliser les Vertex Input Layouts. Voir cet article.

Explications :

Les voici :

 

Résumé :

Nous avons présenté différents types de configurations de vertex dont vous pouvez vous inspirer.

Une classe gestionnaire de textures pour DirectX 10

texture

Intro :

Pour gérer nos fichiers textures au sein d’un moteur 3D, nous allons utiliser un « TextureManager ».

Prérequis :

– Savoir utiliser la classe Singleton. Voir cet article

Explications :

Voici le fichier TextureManager.h :

 

Voici le fichier TextureManager.cpp :

 

Résumé :

Nous avons présenté une classe gestionnaire de chargement de textures.

Obtenir la taille d’une texture ressource shader

equerre

Intro :

Parfois nous avons besoin d’obtenir la taille d’une ressource shader de texture rapidement.

Explications :

Voici comment l’obtenir :

 

Résumé :

Nous avons vu comment obtenir les dimensions d’un ressource shader de texture.

Une classe ShaderTechnique pour représenter facilement vos effets shaders

shader_tech

todo : changer en m_pLayoutDesc

todo : enlever le prefixe des enums !

Intro :

Voici une classe qui vous aidera à déclarer et à définir vos fichiers shaders facilement.

Cette classe gestionnaire vous permettra de définir les variables shaders utilisées et même de paramétrer automatiquement certaines types de variables.

Explications :

Voici le fichier ShaderTechnique.h :

 

Voici le fichier ShaderTechnique.cpp :

 

Résumé :

Cette classe vous permettra de paramétrer vos fichiers shaders facilement.

Entrées clavier et souris avec DirectInput

 

souris

Intro :

DirectInput est un composant de DirectX qui permet de gérer les entrées clavier (touches) et de la souris (position).

Bien qu’il soit tendance à n’être plus utilisé, il est toujours utile car il permet de capturer directement les entrées clavier à partir des drivers périphériques correspondants.

Prérequis :

– Savoir un peu lire du C++.

– Savoir initialiser DirectX 10.1.

– Savoir utiliser la classe Singleton.

Explications :

Voici le fichier InputManager.h :

 

Voici le fichier InputManager.cpp :

 

Résumé :

Avec l’interface DirectInput, on peut élaborer un système d’entrée clavier souris tout simple.

Entrées clavier et souris avec la boucle de message WndProc

keyboard

todo : remplacer les scancodes par les virtual codes

Intro :

A l’inverse de l’utilisation du composant DirectInput de DirectX, nous pouvons directement utiliser les réponses de la boucle de message WndProc en tant qu’entrées clavier-souris.

Cet article fournira la classe InputManager utilisée dans d’autres articles.

Explications :

Voici le code pour le fichier InputManager.h

 

Voici le code pour le fichier InputManager.cpp :

 

Voici la fonction WndProc utilisée pour obtenir les entrées afin de les passer à la classe InputManager :

 

Résumé :

Nous avons présenter une manière de récupérer les entrées clavier de votre jeu ou application.

Voici l’archive du code complet pour cet RawInputManager.zip

Références :

Combiner des paramètres (flags) dans une déclaration enum

bits

Intro :

Parfois on a besoin de combiner et de regrouper des paramètres d’une enum ensemble.

Prérequis :

– Comprendre l’essentiel de la logique booléenne

– Savoir ce qu’est une énumération en C++

Explications :

Par exemple, pour gérer les entrées clavier des touches SHIFT, CTRL, ALT, nous devons parfois les combiner afin d’effectuer une action spéciale dans une application.

On pourrait déclarer ces possibilités par l’énumération de la manière suivante :

Mais on aimerait les combiner avec l’opérateur booléen : | (le ou logique) de la façon suivante :

 

Cette combinaison représente le fait que l’on appuie en même temps sur la touche SHIFT et sur la touche CTRL.

Alors il est nécessaire, pour combiner ces derniers champs, de spécifier des valeurs d’une certaine façon à cette énumération :

Ceci afin de nous permettre de faire des opérations binaires (bitwise) sur ces derniers champs.

Pour simplifier cette dernière déclaration, on utilisera cette macro suivante qui aidera à assigner, dans votre déclaration enum, les différents champs binaires (bit flag)

[code language=cpp]
#define BIT(x) 1 << x
[/cpp]


Mais que fait cette dernière macro ?

Elle remplace les champs de déclarations binaires de manière simple.

 

Résumé :

Nous avons appris comment combiner plusieurs paramètres d’une énumération en C++.

Références :

– http://www.learncpp.com/cpp-tutorial/38-bitwise-operators/

Afficher des caractères accentués dans la console

Intro :

Quand on écrit une chaine de caractères avec des caractères de l’alphabet français (é, ù, ç, à, etc…) dans la console, ils s’affichent de la mauvaise façon.

Exemple :

 

Ensuite il s’affiche dans la console :

 

console_caractères_mauvais

 

Il y a donc un problème de reconnaissance des caractères spéciaux.

Explications :

Une façon de résoudre ce problème est d’utiliser cette fonction :

 

Maintenant on peut afficher correctement les caractères spéciaux :

console_caractères

 

Résumé :

Avec l’alphabet français on ne pouvait pas écrire de texte avec les caractères spéciaux.

Mais avec la fonction Formater() présenté, les caractères s’affichent correctement.

Références :

– http://h-deb.clg.qc.ca/Sujets/AuSecours/Afficher–Accents.html

Une caméra à la première personne (FPS)

Intro :

camera

Pour pouvoir observer nos entités dans une scène 3D, il faut pour cela mouvoir une caméra que l’on peut bouger aisément.

Prérequis :

– Savoir lire et écrire du C++

– Savoir utiliser les objets et fonctions mathématiques de la librairie D3DX

– Savoir ce qu’est une matrice

– Savoir ce que sont les transformations de repère

– Savoir utiliser la classe InputManager utilisée dans le code présenté

– Savoir utiliser les mathématiques des vecteurs (produit vectoriel et produit scalaire)

Explications :

Voici le code tout simplement de notre caméra à la première personne.

A noté l’utilisation de la classe InputManager avec les appels à INPUT_MANAGER dans le code.

Voici le code pour le fichier FPSCamera.h :

 

Voici le code pour le fichier FPSCamera.cpp :

 

Comment se servir du code précédent ? 

Ce qui nous intéresse dans cette implémentation de caméra ce sont la matrice de vue (m_view) et la matrice de projection (m_proj).

Dans votre propre code, avant d’effectuer le rendu de vos modèles 3D vos devez spécifier ces matrices au shader correspondant :

 

Et voilà c’est tout simple !

 

Résumé :

Nous avons implémenté une caméra à la première personne (FPS) qui nous permet de naviguer facilement dans notre scène 3D.

Nous accédons aux matrices de vue et de projection avec les méthodes GetViewMatrix() et GetProjectionMatrix().

Références :

– Introduction to DirectX 9.0c – A shader approach

Rotation autour d’un axe quelconque

Intro :

Voici les matrices de rotation des axes X, Y et Z :

matrix_rotation

Nous savons comment faire une rotation autour des axes X, Y, et Z, mais comment faire une rotation à partir d’un axe quelconque différent des précédents ?

Prérequis :

– Savoir ce qu’est une matrice

– Savoir ce qu’est une transformation de repère

– Savoir utiliser les objets et fonctions mathématiques de la librairie D3DX

Explications :

Nous allons présenter deux méthodes : la formule de Rodrigues en deux variantes et une fonction correspondante de la librairie D3DX.


La formule de Rodrigues suivante permet de calculer la position d’un point subissant une rotation autour d’un axe quelconque.

Les variables sont : \({v} \) la position d’un point qui subit la rotation ; \({\theta} \) un angle de rotation ; \({k} \) vecteur d’unité 1 qui joue le rôle d’axis de rotation.

\({v}_\mathrm{rot} = {v} \cos\theta + ({k} \times {v})\sin\theta + {k} ({k} \cdot {v}) (1 – \cos\theta) \)

Voici l’implémentation de cette formule en C++ :

Une autre formule de Rodrigues permet de calculer rapidement la matrice de révolution autour d’un axe et d’un angle quelconques.

Les variables sont : la matrice de rotation \(\mathbf{R}_{\mathbf{K}}(\theta) \) autour d’un axe \({k} = ( k_{1}, k_{2}, k_{3} ) \) d’unité 1 et d’angle \(\theta \) ; \(\mathbf{I} \) étant la matrice identité ;

et la matrice \(\mathbf{K} = \left[\begin{array}{ccc} 0 & -k_3 & k_2 \\ k_3 & 0 & -k_1 \\ -k_2 & k_1 & 0 \end{array}\right] \)

\(\mathbf{R}_{\mathbf{K}}(\theta) = \mathbf{I} + (\sin\theta) \mathbf{K}+ (1-\cos\theta)\mathbf{K}{^2} \)

Voici l’implémentation de cette formule en C++ :


D’autre part, on peut aussi se servir de la fonction D3DXMatrixRotationAxis équivalente à la précédente formule de Rodrigues :

Résumé :

Nous avons appris deux méthodes qui permet de faire la rotation d’un point.

Références :

– https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula

Structures de DirectX 10

Intro :

1211804249

DirectX 10 utilise différentes structures pour se configurer.
Il peut être utile de les connaître afin de maitriser l’initialisation de DirectX 10.

[à faire]     D3D10_TEXTURE2D_DESC textureDesc;
D3D10_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
D3D10_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;

Les voici énumérées :

– DXGI_SWAP_CHAIN_DESC :

– utilisée pour configurer la Swap Chain au tout début de l’initialisation de DirectX

– D3D10_TEXTURE2D_DESC :

– utilisée pour décrire une surface 2D

– D3D10_BUFFER_DESC :

– utilisée pour décrire un buffer quelconque

– D3D10_RASTERIZER_DESC :

– utilisée pour configurer l’étape Rasterizer de la chaîne de rendu 3D

– D3D10_VIEWPORT :

– utilisée pour configurer un cadre de vue 3D

– D3D10_SAMPLER_DESC :

– utilisée pour décrire l’échantillonnage d’une texture utilisable dans un shader

– D3D10_COMPARISON_FUNC :

– utilisée pour spécifier la fonction de comparaison entre deux valeurs

– D3D10_USAGE :

– utilisée pour spécifier comment est gérée une ressource par le CPU ou le GPU

 –  DXGI_SWAP_CHAIN_DESC :

Explications :

Avant tout configuration de structure, pensez à l’initialiser à zéro avec la macro :

 

Pour DXGI_SWAP_CHAIN_DESC :

On la configure ainsi :

 

Pour D3D10_TEXTURE2D_DESC :

On la configure ainsi :

 

Pour D3D10_BUFFER_DESC :

On la configure ainsi :

 

Pour D3D10_RASTERIZER_DESC :

On la configure ainsi :

 

Pour D3D10_VIEWPORT :

On la configure ainsi :

 

Pour D3D10_SAMPLER_DESC :

On la configure ainsi :

 

Pour D3D10_USAGE :

Voici comment la configurer :

 

Résumé :

Nous avons appris le rôle que joue chaque structure de DirectX 10 afin de mieux comprendre son fonctionnement.

Références :

– DirectX June 2010 SDK Documentation

Calculer la tangente et la bitangente d’une face

NTBFromUVs_cadre

Intro :

Pour certains algorithmes de rendu 3D par shader (comme celui du normal mapping) nous avons besoin, en plus de la normale, de deux vecteurs perpendiculaires à celle-ci : ce sont la tangente et la bitangente (ou binormale).

Voici trois méthode pour les obtenir et les calculer.

Explications :

Mathématiquement, le calcul de ces deux autres composantes autres que la normale s’énonce ainsi :

\(\vec{Edge1} = \vec{V}_2 – \vec{V}_1 \)

\(\vec{Edge2} = \vec{V}_3 – \vec{V}_1 \)

\(\vec{UVEdge1} = \vec{UV}_2 – \vec{UV}_1 \)

\(\vec{UVEdge2} = \vec{UV}_3 – \vec{UV}_1 \)

\(p = (\vec{UVEdge1}_y * \vec{UVEdge2}_x)\, – \,(\vec{UVEdge1}_x * \vec{UVEdge2}_y) \)

\(c = 1 / p \)

\(\vec{Tangent} = [\enspace (\vec{Edge1} * -\vec{UVEdge2}_y) + (\vec{Edge2} * \vec{UVEdge1}_y) \enspace ]\newline * c \)

\(\vec{Bitangent} = [\enspace(\vec{Edge1} * -\vec{UVEdge2}_x) + (\vec{Edge2} * \vec{UVEdge1}_x)\enspace] * c \)

Je vous montre une fonction permettant de calculer la tangente et la bitangente.

Un autre algorithme est disponible si vous ne voulez pas calculer les données face par face !

Voici la troisième fonction (sans doute la meilleure) :

Voilà c’est tout pour les algorithmes !

Sachez que comme vous l’avez vu, la méthode standard indique que la tangente doit être orientée dans la même direction que les coordonnées de texture du triangle en question.

D’autre part ce n’est pas l’objet de cet article, mais je vous apprend que la normale, la binormale et la tangente sont trois vecteurs qui forment une base permettant de transformer les normales issues (et extraites) d’une image RGB spéciale VERS l’espace / coordonnées du modèle du mesh contenant les triangles (bind space ou model space en anglais).

Cette base est représentée mathématiquement par la matrice suivante :

\(\begin{bmatrix} \textbf{T}_x & \textbf{B}_x & \textbf{N}_x \\ \textbf{T}_y & \textbf{B}_y & \textbf{N}_y \\ \textbf{T}_z & \textbf{B}_z & \textbf{N}_z \end{bmatrix} \)

\(\textbf{T} \) représentant la tangente. \(\textbf{B} \) représentant la binormale. \(\textbf{N} \) représentant la normale.

Il ne reste plus qu’à multiplier le vecteur normal par cette matrice est le tour est joué !

Résumé :

Nous avons présenté l’algorithme permettant de calculer les binormales et les bitangentes en utilisant les coordonnées des textures du mesh en question.

Références :

– http://www.3dkingdoms.com/weekly/weekly.php?a=37

– http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/

Un cube tout simple en 3D

cube

Intro :

Voici l’implémentation d’un cube tout simple par la définition de ses vertices et indices.

Il peut être utilisé pour faire des tests ou pour déboguer vos jeux.

Explications :

Dans le fichier Cube.h :

 

Dans le fichier Cube.cpp :

 

Résumé :

Nous avons implémenter le code pour afficher un petit cube.

Voici les fichiers sources : Simple Cube.zip.

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

Intro :

gears2a

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 les événements du gameplay, du son, de l’interface, du réseau, de la gestion des collisions et de l’IA et aussi de pouvoir les invoquer facilement, proprement et de manière élégante.

Ceci constitue la deuxième approche au problème.

Prérequis :

– La compréhension de l’utilisation de la classe DataParameters, voir cet article.

– La compréhension de l’utilisation des delegates en C++11, voir cet article.

Explications :

 

Résumé :

 

Références :

– Game Coding Complete 4 (code LGPL)

Introduction à la programmation réseau (Sockets) – partie 2

48405289

Intro :

Pour concevoir un jeu vidéo multijoueur il vous faut utiliser dans le programme C++ des objets qu’on appelle sockets.

Ceci constitue la deuxième partie de l’ensemble des articles concernant les sockets.

Dans cette partie nous allons concevoir un petit chat en entrant du texte dans la console côté client et côté serveur.

Prérequis :

– Savoir un peu lire et écrire du C++

– Être sous Windows.

– Avoir suivi la première partie de ce tutoriel

Explications :

1 – Tout d’abord nous allons écrire un petit programme de chat par écrit à travers les entrées clavier de l’utilisateur dans la console.

2 – En deuxième partie, j’énumérerais l’ordre d’appel des fonctions sockets selon le rôle du programme (client ou serveur).

 


 

1 – Petit chat client / serveur

Voici le code du chat côté client (ChatClient.cpp) :

 

Voici le code du chat côté serveur (ChatServeur.cpp) :

 


 

2 – Ordre d’appel des fonctions socket selon le rôle de l’application (client ou serveur) :

OrdreTCP

 

Résumé :

Nous avons construit une application client / serveur pour communiquer en messagerie par le biais de la fenêtre console.

Références :

Apprendre le C++

C++-unofficial.sh-600x600

Intro :

Il vous faut apprendre le C++ avant de concevoir des mécanismes internes à la conception de jeux vidéo.

Il existe beaucoup de tutoriels sur comment apprendre à programmer en C++ sur la toile (et en français !)

Je vous liste une série de tutoriels qui m’ont parus intéressants.

Explications :

– L’excellent tutoriel C++ de Mathieu Nebra sur openclassroom.com (anciennement Site Du Zéro) :

http://openclassrooms.com/courses/programmez-avec-le-langage-c

–  La FAQ C++ de developpez.net :

http://cpp.developpez.com/faq/cpp/

Résumé :

Sur ce site je ne vous apprend pas à utiliser le C++ ; je vous fourni cependant quelques tutoriels sur le sujet.