[C++/OpenGL] Génération d'un terrain 3D à partir d'un bitmap
Intéressons nous ici plus particulièrement à la fonction d'affichage d'OpenGL :
* Affichage du terrain *
int i,j; double ajout = CONFIG_taille_carre / CONFIG_max_points,posi,posj; |
Nous allons avoir besoin de quelques variables, i et j des entiers pour le parcours normal de notre "map", ajout est en fait la taille d'un polygone que l'on déduit en faisant cette petite division. Les 2 dernières variables serviront pour l'affichage du terrain et le décalage réel.
glColor3f(1.0f,0.0f,0.0f); // rouge for(i=0,posi=0;i<CONFIG_max_points-1;i++, posi += ajout) { glBegin(GL_TRIANGLES); for(j=0, posj=0;j<CONFIG_max_points-1;j++, posj += ajout){ glVertex3d(posi,posj,map[i][j]); glVertex3d(posi,posj+ajout,map[i][j+1]); glVertex3d(posi+ajout,posj+ajout,map[i+1][j+1]); glVertex3d(posi,posj,map[i][j]); glVertex3d(posi+ajout,posj+ajout,map[i+1][j+1]); glVertex3d(posi+ajout,posj,map[i+1][j]); } glEnd(); } |
On commence par définir la couleur des traits, avec la fonction glColor3f ( R, G , B ). On entre alors dans une double boucle dans laquelle i et j sont incrémentés de 1 pour parcourir le tableau des hauteurs. On a également posi et posj qui représentent la position réelles dans le plan.
Remarque : on aurait très bien pu remplacer les posi par (i * ajout) et posj par (j * ajout) mais étant donné que chaque variable est utilisée 6 fois par tour de boucle, donc 12 fois en tout, en faisant l'addition à chaque tour de boucle, vous économiserez pas mal de calcul.
Ensuite, le positionnement des sommets se fait selon une technique rectangulaire, on pose 2 triangles côte à côte pour former un carré ! Alors pourquoi ne pas dessiner directement un carré ? Et bien il faut s'habituer aux triangles, ils sont bien mieux appropriés à la 3D, et évite d'avoir des soucis au niveau de l'affichage de certaines formes. De plus ils permettent une meilleure précision mais évidemment cela à un coût : 2 sommets supplémentaires ...
Voici la différence de rendu filaire :
On remarque une différence assez flagrante au niveau de la précision tout de même. Alors existe t-il une meilleure solution pour l'affichage triangulaire ? Et bien, oui il existe deux autres modes triangulaires : GL_TRIANGLE_STRIP et GL_TRIANGLE_LOOP.
Le premier calcule pour vous les points intermédiaires entre chaque triangles, et les accrochent pour vous, le dernier relie simplement le dernier triangle au premier triangle. En gros 4 sommets suffisent pour avoir nos 2 triangles.
* Optimisation *
Utilisons donc GL_TRIANGLE_STRIP pour optimiser le nombre de polygones.
Voici le résultat :
Et le code donc :
for(i=0,posi=0 ;i |