Changes for rapport/rapport.md: 15 added lines, 17 removed lines.
Original line number
Diff line number
Diff line
@@ -13,17 +13,15 @@ classoption: oneside
colorlinks: true
...
# (sp)Ace Combat - rapport
# Introduction
## Introduction
### Genèse du projet
## Genèse du projet
**(sp)Ace Combat** (en référence au simulateur de combat aérien [Ace Combat](https://fr.wikipedia.org/wiki/Ace_Combat)) est notre projet pour la matière "Synthèse d'image" du M1 Info 2021-2022.
Il s'agit d'un simulateur de combat spatial (*space dogfight*) permettant, en accord avec le thème imposé, de jouer à deux joueurs sur le même clavier. Il est construit sur l'interface OpenGL **glitter**, modifiée par endroits pour permettre un meilleur traitement de certaines données.
### Objectifs initiaux
## Objectifs initiaux
Au début du projet, nous avons décidé de nous fixer des objectifs principaux (devant être atteints à la fin du projet) et secondaires (destinés à n'être réalisés que si nous avions assez d'avance). Voici les objectifs primaires :
@@ -40,7 +38,7 @@ Et voici les objectifs secondaires :
- [x] Détecter les collisions vaisseau-vaisseau
- [x] Ajouter des obstacles (astéroïdes)
- [ ] Détecter les collisions vaisseau-obstacles
- [] Spécialiser le déplacement des vaisseaux
- [x] Spécialiser le déplacement des vaisseaux
- [ ] Ajouter une physique newtonienne aux vaisseaux
- [x] Ajouter des écrans de fin de partie
@@ -50,9 +48,9 @@ De plus, nous nous sommes fixé les contraintes suivantes pour ne pas nous épar
- Gérer les collisions de la manière la plus réaliste possible
- Rendre le code le plus modulaire possible
## Programmation
# Programmation
### Modifications apportées à *glitter*
## Modifications apportées à *glitter*
Nous avons dû modifier quelque peu glitter afin de permettre de mieux gérer certains éléments de notre projet :
@@ -61,7 +59,7 @@ Nous avons dû modifier quelque peu glitter afin de permettre de mieux gérer ce
- La touche `Space` ne bloque plus les updates du jeu
- Possibilité d'envoyer des *boléens* aux *shaders* sous la forme d'*uniforms*
### Système d'entités
## Système d'entités
Le système d'entités est géré par la classe `model/Entity`. Cette classe a pour but de gérer une unité dans l'espace 3D, notamment de gérer sa position, sa rotation, son échelle (qui peuvent ensuite être transmis sous la forme d'une "model matrix" au `glapi` de glitter)
@@ -69,7 +67,7 @@ Nous avons décidé, de par notre nombre d'entités, de simplifier cette classe
Ce système permet de ne charger qu'une seule fois chaque modèle 3D, et donc de ne créer qu'une seule boite de collision par modèle.
### Gestion des collisions
## Gestion des collisions
Nous avons décidé, en accord avec nos objectifs, d'utiliser des **OBB** (*oriented bounding boxes*, boîtes d'encadrement orientées). Celles-ci ont divers avantages et inconvénients en comparaison des plus traditionnelles **AABB** (*axis-aligned bounding boxes*, boîtes d'encadrement alignées sur les axes).
@@ -83,31 +81,31 @@ La plus grande différence entre ces deux types de "boîtes de collision" est le
Cette dernière méthode a été implémentée par nos soins en nous basant sur le papier [*Dynamic Collision Detection using Oriented Bounding Boxes*, par David Eberly](https://www.geometrictools.com/Documentation/DynamicCollisionDetection.pdf). Notre version prend en compte la vélocité des objets comparés, ce qui nous permet de détecter les collisions entre les vaisseaux et entre missiles et vaisseaux. La gestion des collisions est gérée par la classe `Entity`.
### La *skybox*
## La *skybox*
La *skybox* désigne le "décor de fond" de notre jeu. Elle tire son nom du fait qu'elle est traditionnellement utilisée dans des jeux se déroulant sur le sol pour afficher un ciel. Notre skybox représente l'espace, plus particulièrement une nébuleuse. C'est un cube englobant le terrain, et ayant pour texture une image générée aléatoirement grâce au site [tyro.net](https://tools.wwwtyro.net/space-3d/index.html).
### La gestion des rotation
## La gestion des rotation
Notre gestion des rotations s'est d'abord basée sur les angles d'Euler. Cependant, nous avons rapidement remarqué que l'utilisation de ces angles comportait certains problèmes. Nous avons notamment été confrontés au **Gimball Lock** (verrouillage de cadran). Ce problème intervient lorsque deux des axes de rotation d'Euleur se superposent, faisant alors perdre un degré de liberté à l'objet (deux angles de rotation deviennent équivalents et évoluent de la même manière).
Pour éviter ce problème, nous avons décidé d'utiliser des **quaternions** pour gérer les rotations. Là ou les angles d'Euler se basent sur des axes de rotations, les quaternions définissent un vecteur servant d'axe de rotation, puis un angle représentant la rotation effective autour de cet axe.
### La génération du terrain
## La génération du terrain
Le terrain est généré de sorte à ce que des obstacles (sous forme d'astéroïdes) soient générés aléatoirement, avec un tirage type monte-carlo : une zone de protection est définie autour des vaisseaux pour s'assurer que ceux-ci ne puissent pas apparaître en contact avec un astéroïde.
### Système de GUI
## Système de GUI
Le système de GUI passe par une classe `GuiElement` ainsi qu'un shader qui lui est spécialement réservé (disponible dans *shaders/gui.f.glsl* et *shaders/gui.v.glsl*). Il est extrêmement simple car il ne fait qu'afficher une texture sur un rectangle en 2D. L'espace de coordonnées a été quelque peu modifié afin que le coin en bas à gauche de la fenêtre corresponde aux coordonnées (0, 0) et que le coin en haut à droite de la fenêtre corresponde à (1, 1). Cette méthode nous permet d'avoir des dimension et une position relatives à la dimension de la fenêtre. À l'inverse, si nous avions utilisé un système basé sur le nombre de pixels disponible dans la fenêtre, il aurait fallut recalculer la taille et la position des différents éléments du GUI en fonction de comment la fenêtre se redimensionne. Notre méthode permet donc de gérer cela de manière bien plus simple puisque le placement et les dimensions des éléments sont relatifs aux dimensions de la fenêtre.
Comme pour les entités, les éléments du GUI sont ajoutés dans leur propre tableau (`std::vector<std::shared_ptr<GuiElement>>`) ce qui permet d'optimiser leur rendu en limitant les opération de *bind* notamment. Ils sont également séparés des entités puisqu'il faut au préalable désactiver les tests de 3D afin qu'OpenGL les "dessine" bien au dessus de ce qui à précédemment été dessiné.
### *Split-screen* (écran partagé)
## *Split-screen* (écran partagé)
La gestion du *split-screen* est très simple. Il suffit de changer le viewport d'OpenGL (comprendre par là la zone de la fenêtre sur laquelle OpenGL va dessiner). On va d'abord définir le viewport comme faisant toute la largeur de la fenêtre et la moitié de sa hauteur totale avant de dessiner une première fois la scène en plaçant la caméra derrière le vaisseau du premier joueur. On définit ensuite la zone comme étant l'autre moitié de la fenêtre, on place la caméra derrière le vaisseau du le second joueur et on dessine une nouvelle fois la scène dans son intégralité.
## Règles du jeu
# Règles du jeu
Le jeu est basé sur des règles simples : chaque joueur contrôle un vaisseau. Au début du jeu, ceux-ci apparaissent face-à-face à une certaine distance permettant le déplacement sans trop d'encombres.
@@ -119,7 +117,7 @@ Chaque vaisseau dispose de 3 points de vie, et perd l'un d'eux à chaque tir re
À la fin d'une partie, un écran de bilan est affiché, et appuyer sur la touche `Entrée` relance une nouvelle partie.
## Axes d'amélioration
# Axes d'amélioration
Le programme dans son état actuel possède plusieurs axes d'amélioration :