Génération de terrain
(1/2) Par Xavier Michelon |
Le principe de champs de
hauteur que nous allons mettre en place est relativement simple à comprendre.
Dans un premier temps, nous allons générer un maillage carré dans le plan XY.
Le maillage est illustré sur la figure 2. Ce n’est en fait ni plus ni moins
qu’un ensemble de polygones carrés (on utilisera le terme de patch pour distinguer
les petits carrés du maillage complet) collés les uns aux autres. L’opération
se réalise très facilement avec deux boucles imbriquées. Une fois le maillage
créé, il n’y a plus qu’à affecter aux sommets de chaque patch une coordonnée
en Z. En fonction de la position du sommet considéré dans le maillage, on établit
une correspondance avec un pixel de l’image en niveaux de gris. Si le pixel
correspondant est noir, l’élévation du sommet sera minimale, alors que s’il
est blanc, la hauteur sera maximale. Comme vous le voyez, ce n’est pas très
compliqué.
Figure
2 : le maillage vu de dessus
|
Des polygones qui dégénèrent
En utilisant le principe que je viens d’énoncer, nous allons être confrontés à un léger problème : nous allons créer des polygones dégénérés. OpenGL définit strictement les propriétés que doit respecter un polygone pour obtenir un rendu correct. Les polygones doivent entre autres être convexes (i.e. toute ligne joignant deux points quelconques du polygone doit être entièrement comprise dans le polygone), non auto-intersectants et tous les points doivent être dans un même plan. Or cette dernière condition n’est pas vérifiée lorsque l’on génère le terrain puisque les valeurs d’élévation des sommets sont issues d’une image, et il y a finalement peu de chance pour que les 4 sommets de chaque patch soient dans un même plan. Dans le cas d’affichage en mode fil de fer, la dégénérescence des polygones ne pose pas de problème. En revanche, si on éclaire la scène, le rendu des faces en mode plein sera faux. Autant prendre les devants et afficher quelque chose de correct en mode fil de fer.
Figure
3 : le maillage avec les arêtes transversales
|
La solution au problème de dégénérescence est relativement simple : il suffit de décomposer chacun de nos patches en deux triangles. Notre maillage global ressemble donc à la figure 3. Reconnaissez que l’arête transversale est relativement disgracieuse. Nous allons nous en débarrasser en utilisant la fonction glEdgeFlag() d’OpenGL. Le drapeau d’arête (Edge Flag) est une bascule OpenGL qui permet de n’afficher que certaines arêtes d’un polygone. Le prototype de glEdgeFlag est le suivant :
void glEdgeFlag(Glboolean valeur);
‘valeur’ peut valoir TRUE ou FALSE. Les arêtes dont le premier sommet est défini lorsque le drapeau est sur TRUE seront affichées. En revanche si le drapeau est sur FALSE, l’arête n’est pas affichée. Bien sur tout ceci n’a d’intérêt que lors d’un affichage en mode fil de fer. L’exemple ci dessous montre comment dessiner un patch carré en utilisant deux patches triangulaires et la fonction glEdgeFlag() :
/* Dessin du triangle 1 */ glBegin(GL_POLYGON); glEdgeFlag(TRUE); glVertex3fv(P1); glVertex3fv(P2); glEdgeFlag(FALSE); glVertex3fv(P3); glEnd(); /*Dessin du triangle 2 */ glBegin(GL_POLYGON); glVertex3fv(P1); glEdgeFlag(TRUE); glVertex3fv(P3); glVertex3fv(P4); glEnd();
|