Archives de catégorie : Game programming

Programmation de jeux-vidéo

Calculer le nombre d’images par seconde

Q3_HUD_gameplay

Intro : 

Dans les jeux ou les applications graphiques il peut être utile de savoir combien d’images par seconde sont affichées à l’écran pendant le rendu.

Prérequis :

– Savoir initialiser DirectX 10.1

Explications :

Voici le code pour calculer le temps de rafraichissement par seconde, cette méthode devra être appelée à chaque boucle de rendu.
Il est calculé aussi le temps que met, à peu près, le rendu pour afficher une image.


Résumé :

Nous avons présenté comment calculer le FPS (Images par seconde) dans une application de rendu.

Références : 

Introduction to DirectX 9.0c – A shader approach – Franck D. Luna

Une simple grille en 3D

grid

Intro :

Savoir créer une grille en 3D peut être utile pour :

– un éditeur de map

– générer un terrain à partir d’une height map

– représenter la surface d’une eau en mouvement

– etc…

Prérequis :

– Savoir initialiser DirectX 10.1

Explications :

Le fichier Grid.h :

 

Le fichier Grid.cpp :

 

Résumé :

Nous avons expliqué comment générer une grille en 3D avec le paramétrage de sa longueur et de sa largeur puis la dimensions de ses faces.

Voici les fichiers sources : Simple Grille.zip

Références :

– Introduction to DirectX 9.0c – Frank D. Luna

Créer un curseur de souris customisé pour votre jeu

wow_cursors

Intro :

Dans un jeu, il peut être plus joli de changer l’image du curseur de la souris en fonction de ce que pointe la souris.

Prérequis :

– Savoir lire du C++

– Savoir initialiser DirectX 10 à travers la classe System

Explications :

– Téléchargez un curseur (par exemple WoW.cur)

– Créez un fichier « Res.rc » :

 

– Créez un fichier « Ressource.h » :

Mettez ces fichiers dans le dossier des fichiers de ressources :

ressource

Voici la fonction pour fixer le curseur de la souris sur la fenêtre de rendu :

 

Il vaut mieux utiliser l’appel à la fonction SetClassLong que l’appel à la fonction SetCursor ;
en effet le programme gardera constamment l’image de la souris même si le pointeur de souris sort de la fenêtre.

Résumé :

Nous avons présenté une méthode permettant de changer l’image du curseur de la souris.

Une classe pour afficher des lignes en 3D avec une certaine couleur

3D_lines

Intro :

Il peut être utile d’afficher des lignes dans la surface de rendu ; par exemple pour représenter des normales, des trajectoires, un repère, etc…

Prérequis :

– Savoir lire du C++

– Savoir utiliser la classe MeshSceneNode

– Savoir utiliser la classe ShaderTechnique et les déclarations de vertices.

Explications :

Voici le fichier Vertex3DLine.h :

 

Voici le fichier Vertex3DLine.cpp :

 

Voici le fichier ShaderTechnique_Vertex3DLine.h :

 

Voici le fichier ShaderTechnique_Vertex3DLine.cpp :

 

Voici le fichier 3DLine.fx correspondant :

 

Résumé :

Nous avons présenté un système permettant d’afficher des lignes dans la surface de rendu tout en pouvant spécifier leur couleur.

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 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.

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 :

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

Un Performance Timer pour synchroniser vos entités

timer-image

Intro :

Dans un jeu, il peut être utile de calculer le temps entre chaque affichage pour synchroniser la mise à jour de certaines entités.

En effet la vitesse de calcul fait par votre processeur peut rendre la vitesse de ces entités trop rapide.

Par exemple la vitesse de déplacement d’un modèle peut être plus rapide sur la machine d’un PC avec un processeur plus rapide que le vôtre, parce que la boucle de rendu est appelée plus fréquemment que chez vous.

Un mécanisme de calcul du temps passé entre chaque rendu d’affichage permet de pallier ce problème.

Prérequis :

– Savoir lire du C++.

Explications :

Nous allons utiliser la fonction QueryPerformanceCounter qui donne le temps présent en « count ».

On fait la soustraction : B – A, et on a le temps passé (en count) entre l’exécution de ces instructions !

D’autre part il nous faut le temps en seconde (et non en count !)

Dond avec la fonction QueryPerformanceFrequency on obtient le count par seconde.
On aura donc le temps escompté en seconde !

 

Le nombre de secondes escompté en un count est calculé par :


Temps passé entre chaque affichage :

On peut calculer le temps passé entre chaque rendu d’affichage. Notons t le temps passé ;
et \(t _{i} \) le temps passé depuis le ième affichage et \(t _{i-1} \) le temps passé depuis le précédent affichage.

\(\Delta t = t _{i} { – } t_{i-1} \)

 

On calcule ainsi le temps passé entre chaque affichage. On utilise cette valeur de temps afin de synchroniser la mise à jour de nos entités dans la boucle de rendu :

 

Voici un exemple de mise à jour d’une entité en utilisant la valeur fTimeSinceLastFrame (toujours changeante) :

 

Résumé :

Nous avons vu de quelle façon synchroniser la mise à jour de vos entités de façon à ce qu’elles varient dans le temps à la même vitesse sur toutes les machines.

Génération procédurale d’un labyrinthe 3D

laby

Intro :

La génération procédurale d’un contenu par un quelconque algorithme permet de le créer de manière intelligente !

Dans cet article nous allons voir comment générer à la volée un labyrinthe en 3D.

Prérequis :

– Savoir lire du C++.

– Savoir ce qu’est un vertex buffer et un index buffer.

– Savoir manipuler un tableau à deux dimensions.

Explications :

Nous allons utiliser une classe Array2D qui nous permettra de manipuler un tableau à deux dimensions.

Voilà le code pour ce tableau spécial et simple d’utilisation (Array2D.h) :

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

Références :

– http://www.mazeworks.com/mazegen/mazetut/

Caméra à la 3ème personne trigonométrique

caméra

Intro :

Pour se déplacer dans la scène 3D il faut mouvoir une caméra.

Dans cet article nous allons implémenter une caméra qui tourne autour d’un joueur (ou autour d’une position)

Prérequis :

– Comprendre un minimum de notions trigonométriques

Explications :

Déclarer ces trois variables dans un fichier quelconque :

 

Voilà les fonctions d’initialisation et de mise à jour de la caméra à la 3ème personne :

Résumé :

Nous avons présenté un moyen d’implémenter une caméra trigonométrique qui opère une révolution autour de la position du joueur !

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.

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.

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)