Archives de catégorie : Algorithmes

Utilisation de la librairie Zlib pour gérer des flux de compression

zlib3d-b1

Intro :

Il est très utile de pouvoir compresser des données en mémoire ou des fichiers sur disque ou mémoire de masse. Pour cela, on va utiliser la fameuse librairie C open-source nommée Zlib !

Prérequis :

– Savoir lire du C ou du C++

– Savoir configurer l’importation d’une librairie sous Visual C++

Explications :

Elle implémente l’algorithme de compression deflate et peut créer des fichiers au format gzip.
La bibliothèque est aussi multi-plateforme.

Résumé :

Nous avons présenté une classe C++ encapsulant les fonctions de compression de la librairie Zlib ; cette classe permet de compresser des fichiers ou des données en mémoire.

Références :

– http://www.zlib.net/manual.html

– http://www.zlib.net/zlib_how.html

– http://www.zlib.net/zlib_faq.html

Apprendre à utiliser TinyXML pour charger vos fichiers XML

tinyxml

Intro :

Parfois dans un programme ou un jeu vidéo, il est nécessaire de charger des données sous format XML. Par exemple pour un éditeur de scène / monde, on peut vouloir charger les positions des entités directement depuis un fichier Scene.xml par exemple.

Prérequis :

– Savoir lire du C++

– Savoir lire un fichier XML

– Savoir importer des fichiers sources dans Visual C++

Explications :

TinyXML est une toute petite librairie C++ permettant de charger et d’analyser les données stockées dans un fichier XML. Elle est sous la licence Zlib (cela signifie que vous pouvez l’utiliser pour n’importe quoi !)

D’abord il vous faut télécharger les sources de TinyXML. La dernière version à la date d’écriture de cet article est la version 2.

Deux choix s’offrent à vous : soit d’utiliser la version 1 ; soit d’utiliser la version 2.

Les avantages de choisir la 2ème : meilleur gestion de la mémoire ; lecture plus rapide du fichier XML ; pas d’utilisation de la STL.

TinyXML charge complètement un fichier XML avec la méthode LoadFile()… Il vous reste ensuite le soin d’analyser votre fichier XML en fonction de son contenu en terme de nœuds.

On précise que XML est l’abréviation de « eXtensible Markup Language ». XML est un format pour stocker des données, pas un langage de programmation !
Celles-ci sont écrites entre des balises ou sous forme d’attributs, et l’ensemble est écrit sous forme d’un arbre.

Voici la structure d’un fichier XML :
 

Il vous faut importer dans votre projet Visual C++ la librairie directement par l’intermédiaire de ces fichiers :

– tinystr.cpp
– tinyxmlerror.cpp
– tinystr.h
– tinyxml.h
– tinyxml.cpp
– tinyxmlparser.cpp

 

Dans votre fichier source .cpp utilisant TinyXML, il vous faudra écrire #include « tinyxml.h » en tant que fichier d’en-tête.

Vous pouvez définir le define #define TIXML_USE_STL pour activer l’utilisation de la STL dans TinyXml.

Sachez que TinyXML reconnaît automatiquement l’encodage utilisé par le fichier à charger (il n’est pas nécessaire de renseigner l’attribut « encoding »).

Commençons l’analyse d’un fichier quelconque :

 

Le fichier « doc » contient toutes les données d’analyse du fichier XML chargé.

 

La méthode FirstChildElement() renvoie un pointeur vers un objet TinyXmlElement qui représente le premier nœud du fichier XML en question. FirstChildElement() prend un paramètre une chaîne de caractères représentant le nom du nœud en question.

Une boucle permet d’afficher tout les noms des éléments du fichier :

 

Le principe est le suivant : on parcourt chaque nœud en extrayant de chaque nœud enfant les attributs qui nous intéressent !

 

La variable attr représente la valeur de l’attribut en question. Si l’attribut ne comporte pas le nom spécifié. La méthode Attribute(…) renvoie nullptr.

On peut tester si le contenu d’un nœud est du texte avec la méthode elem->ToText(). Elle renvoie nullptr s’il n’y a pas de texte.

Il peut être utile d’utiliser une structure de données spécifique customisée afin de stocker les données lues depuis le fichier XML. Mais cela reste facultatif !

On fini l’analyse avec l’appel de Clear() : doc.Clear();

Pour faciliter le parcours des nœuds, on peut utiliser ce qu’on appelle des handles.
Exemple :

 

La méthode QueryIntAttribute(…) permet d’obtenir la valeur d’un attribut sous forme de integer

Voici la liste des classes de TinyXML formatée par Doxygen : http://www.grinninglizard.com/tinyxmldocs/annotated.html

Résumé :

Simple et efficace, la petite librairie TinyXML facilitera vos chargement de données sous format XML.

Références :

– http://www.dinomage.com/2012/01/tutorial-using-tinyxml-part-1/

Comment calculer la matrice de rotation d’un Billboard

tag

Intro :

Qu’est-ce un billboard ? Un billboard est un objet 3D (en général d’apparence 2D) qui fait toujours face à la caméra.

Prérequis :

– Savoir ce qu’est une matrice

– Savoir lire une matrice

– Savoir en quoi consiste la matrice de vue

Explications :

Rappelez vous que la matrice de vue (celle de la caméra) est définie ainsi :

viewmatrix

En effet, cette matrice est construite à partir de trois vecteurs :

uprightlook

Avec une origine (ainsi nommée « Caméra ») représentant la position de celle-ci par rapport au repère commun à tous les nœuds de la scène, cette dernière concerne la matrice World (matrice de monde)

Une fois construite, la matrice de vue est une matrice qui doit être mise à jour constamment dans la boucle de rendu.

Décomposition de la matrice View :

\(\vec{LookAt}_x = \textbf{View}_{02} \)
\(\vec{LookAt}_y = \textbf{View}_{12} \)
\(\vec{LookAt}_y = \textbf{View}_{22} \)

\(\vec{Right}_x = \textbf{View}_{00} \)
\(\vec{Right}_y = \textbf{View}_{10} \)
\(\vec{Right}_y = \textbf{View}_{20} \)

\(\vec{Up}_x = \textbf{View}_{01} \)
\(\vec{Up}_y = \textbf{View}_{11} \)
\(\vec{Up}_y = \textbf{View}_{21} \)

On normalise ensuite ces trois derniers vecteurs :

\({\vec{LookAt}}_{norm}=\frac{{\vec{LookAt}}}{\|{\vec{LookAt}}\|} \)
\({\vec{Right}}_{norm}=\frac{{\vec{Right}}}{\|{\vec{Right}}\|} \)
\({\vec{Up}}_{norm}=\frac{{\vec{Up}}}{\|{\vec{Up}}\|} \)

A noter que l’on peut retrouver un vecteur connaissant les deux autres. Par exemple, l’on veut retrouver le vecteur \({\vec{Up}} \) connaissant \({\vec{Right}} \) et \({\vec{LookAt}} \). On procède ainsi  :

\({\vec{Up}} = {\vec{LookAt}}\times{\vec{Right}} \)

Maintenant pour construire notre Billboard il nous faudra créer une matrice de rotation \(\textbf{R} \). C’est avec cette matrice de rotation que seront multipliés toutes les vertices du Billboard de façon à ce qu’ils soient toujours en face de la caméra !

On calcule la matrice \(\textbf{R} \) de la façon suivante :

\(\textbf{R}_{0*} = {\vec{Right}} \)
\(\textbf{R}_{1*} = {\vec{Up}} \)
\(\textbf{R}_{2*} = {\vec{LookAt}} \)

C’est-à-dire de manière plus détaillée :

\(\textbf{R}_{01} = \vec{Right_x} \)
\(\textbf{R}_{02} = \vec{Right_y} \)
\(\textbf{R}_{03} = \vec{Right_z} \)

\(\textbf{R}_{11} = \vec{Up_x} \)
\(\textbf{R}_{12} = \vec{Up_y} \)
\(\textbf{R}_{13} = \vec{Up_z} \)

\(\textbf{R}_{21} = \vec{LookAt_x} \)
\(\textbf{R}_{22} = \vec{LookAt_y} \)
\(\textbf{R}_{23} = \vec{LookAt_z} \)

Voici le Vertex Shader qui applique le calcul en question :

Voici un Billboard affiché qui représente une quête disponible :

billboard

Résumé :

Nous avons expliqué comment créer un Billboard en construisant une matrice de rotation spéciale qui tourne et qui fait toujours face à la caméra.

Références :

– Des sujets issus de quelques forums Internet comme celui de www.gamedev.net

Une classe DelayedTimerManager pour gérer les délais de temporisation

unnamed

Intro :

Parfois nous avons besoin, dans le code, d’appeler des fonctions / méthodes à un certain intervalle de temps !

Prérequis :

– Savoir lire du C++

Explications :

Voici le fichier DelayedTimerManager.h :

 

Voici le contenu du fichier DelayedTimerManager.cpp :

 

Résumé :

Nous avons présenter le code pour gérer un système de temporisation.

La technique du back-face culling

backface

Intro :

La technique du back-face culling permet d’ignorer le rendu des triangles qui ne sont pas visible par l’observateur ou la caméra.

Prérequis :

–  Savoir ce qu’est un produit scalaire

Explications :

Par exemple, les triangles de l’intérieur d’un modèle ou personnage ne seront pas rendu si l’on rentre et se positionne dedans !

Bacfaceculling

Dans DirectX, les vertices d’un triangle sont définis dans un certain ordre (il existe deux sens : le sens « counter clockwise » et le sens « closewise»). Cet ordre va définir dans quel sens est orienté la normale du triangle en question (voir l’article sur la normale).

clock_wise

Comment ça fonctionne ?

Soit le vecteur représentant la position de la caméra \(\vec{c} \) ; et le vecteur représentant la position du centre du polygone à tester \(\vec{p} \).

On calcule donc le vecteur \(\vec{v} = \vec{p} – \vec{c} \)

On a aussi le vecteur normal à ce même polygone \(\vec{n} \)

Mathématiquement :

\(k = \vec{v} \cdot \vec{n} \)

 

Si le produit scalaire \(k \) est positif (en fait cela dépend du type de culling) alors cela signifie que le triangle est orienté dans le même sens que la vue (il nous tourne le dos), et il peut donc être éliminé du rendu.

Voilà c’est tout simple !

Il faut savoir aussi que cet algorithme est géré automatiquement par DirectX et la carte graphique.

On peut le configurer comme suit :

 

Résumé :

Pour conclure, le backface culling est l’élimination des faces qui « tournent le dos » à la caméra et que l’on ne voit donc pas.

Références :

– http://jeux.developpez.com/faq/3d/?page=culling

– http://stackoverflow.com/questions/3595087/opengl-newbie-question-what-is-back-face-culling

– http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/3d-backface-culling-r1088

– https://en.wikipedia.org/wiki/Back-face_culling

– https://fr.wikipedia.org/wiki/D%C3%A9termination_des_surfaces_cach%C3%A9es

Générer une sphère MeshSceneNode

Sphere

Intro :

Il peut être utile de savoir générer une sphère à la volée par la définition de ses vertices et de ses indices.

Prérequis :

– Savoir lire du C++

– Savoir initialiser DirectX 10

– Savoir utiliser et comprendre un peu de trigonométrie

– Savoir utiliser la classe Renderable

– Savoir utiliser la classe MeshSceneNode

– Savoir utiliser la classe ShaderTechnique

Explications :

Voici l’implémentation de la classe shader :

 

Voici le fichier ShaderTechnique_BasicTexture.cpp :

 

Voici le fichier SphereMeshSceneNode.h :

 

Voici le fichier SphereMeshSceneNode.cpp :

 

Résumé :

Nous avons appris comment générer une sphère en 3D avec ses coordonnées de texture et normales.

Référénces :

– http://stackoverflow.com/questions/5988686/creating-a-3d-sphere-in-opengl-using-visual-c