Le cube tournant en OpenGL
Par Xavier Michelon


 
 
Le tampon de profondeur :

Le passage du carré 2D au cube 3D fait surgir un nouveau problème : celui de l'ordre d'affichage des polygones de la scène. La dernière fois, la scène ne comportait qu'un polygone et donc la question ne se posait pas. Aujourd'hui, avec nos 6 faces, il est important d'ordonner correctement l'affichage. Pour vous en convaincre, prenez une feuille de papier, et 6 crayons de couleurs. L'objectif est de dessiner un cube vu de coté dont chaque face sera remplie avec une couleur. Afin de simuler le comportement (relativement stupide) d'un ordinateur, je vais vous demander de colorier chacune des faces du polygones, même celles qui seront entièrement masquées par d'autres faces. Vous comprenez bien qu'il faut choisir judicieusement l'ordre dans lequel vous devez colorier les faces pour obtenir un résultat correct : il faut commencer par colorier les faces qui sont les plus éloignées du point de vue.

Pour résoudre ce problème de faces cachées, OpenGL propose une technique extrêmement répandue en synthèse d'images : le tampon de profondeur, plus connu sous son nom anglais : Z-buffer. Le tampon de profondeur est une technique simple et très puissante. L'idée principale est de créer en plus de notre image un tampon de même taille. Ce tampon va servir à stocker pour chaque pixel une profondeur, c'est-a-dire la distance entre le point de vue et l'objet auquel appartient le pixel considéré. A l'origine, le tampon est rempli avec une valeur dite "de profondeur maximale" : l'image est vide. A chaque fois qu'on dessine un polygone, pour chaque pixel qui le constitue, on calcule sa profondeur et on la compare avec celle qui est déjà stockée dans le tampon. Si la profondeur stockée dans le tampon est supérieure à celle du polygone qu'on est en train de traiter, alors le polygone est plus proche (au point considéré) de la caméra que les objets qui ont déjà été affichés. Le point du polygone est affiché sur l'image, et la profondeur du pixel est stockée dans le tampon de profondeur. Dans le cas inverse, le point que l'on cherche à afficher est masqué par un autre point déjà placé dans l'image, donc on ne l'affiche pas. Vous noterez qu'avec cette technique, on peut afficher les polygones dans un ordre quelconque.

Nous allons mettre en place un tampon de profondeur pour notre programme. Première chose à faire, il faut modifier l'appel à la fonction glut d'initialisation de l'affichage pour lui indiquer qu'il faut allouer de l'espace pour le tampon de profondeur :

glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH); 

L'utilisation ou non du tampon de profondeur est gérée par une variable d'etat OpenGL : GL_DEPTH_TEST. L'activation du tampon de profondeur se fait en plaçant la ligne suivante dans la phase d'initialisation du programme :

glEnable(GL_DEPTH_TEST);

Tout comme le tampon image, il faut effacer le tampon de profondeur à chaque fois que la scène est redessinée. Il suffit de modifier l'appel glClear() de la fonction d'affichage :

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Afin de vous permettre de visualiser l'intérêt du tampon de profondeur, je vous propose de donner à l'utilisateur la possibilité d'activer et de désactiver le tampon de profondeur avec les combinaisons de touches 'd' et 'Shift'+'d'. Pour cela, ajoutons ces quelques lignes a notre fonction de rappel clavier() :

case 'd':
  glEnable(GL_DEPTH_TEST);
  glutPostRedisplay();
  break;
case 'D':
  glDisable(GL_DEPTH_TEST);
  glutPostRedisplay();
  break;