Première pyramide et premier cube

Jeff Molofee (NeHe)

Traducteur

Miles

À partir du précédent tutoriel, nous allons maintenant créer de vrais objets 3D, plutôt que des objets 2D dans un monde 3D. Nous allons effectuer cela en ajoutant des côtés à gauche, à droite et à l'arrière du triangle ainsi que des côtés à gauche, à droite, à l'arrière, au-dessus et en dessous du carré. Par cette opération, le triangle deviendra une pyramide – plus précisément un tétraèdre – et le carré un cube. ♪

- Titre : Première pyramide et premier cube

- Auteur : Jeff Molofee (NeHe)

- Traducteur : Miles

- Parution : 23 mars 2007

- Mise à jour : 19 décembre 2012

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2007 Nehe Gamedev.net. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Contributions

- II. Tutoriel

- III. Téléchargements

- IV. Remerciements

- V. Liens

I - Contributions

Nous recherchons toujours des traducteurs pour finir ce projet de traduction des articles de NeHe. Votre aide serait appréciée ! Vous êtes intéressé ? Alors contactez-nous à l'adresse suivante : nehe@redaction-developpez.com.

II - Tutoriel

On va mélanger les couleurs sur la pyramide, créant un objet coloré tandis que pour le carré, on colorera chaque face avec une couleur différente.

La fonction DrawGLScene

int DrawGLScene(GLvoid)             // C'est ici que nous ferons le dessin
{
// Efface l'ecran, le tampon de couleur et le tampon de profondeur
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();                // Reinitialise la vue
glTranslatef(-1.5f,0.0f,-6.0f);  // Se deplace vers la gauche vers l'interieur de l'ecran
glRotatef(rtri,0.0f,1.0f,0.0f);  // Tourne la pyramide sur son axe Y
glBegin(GL_TRIANGLES);           // Debut du dessin de la pyramide

Certains d'entre vous auront repris le code du tutoriel précédent et fabriqué leurs propres objets 3D. Une des questions que je me posais fréquemment était « Comment cela se fait-il que mes objets ne tournent pas sur leurs axes ? Il semble qu'ils tournent partout sur l'écran ». Afin de faire tourner votre objet autour d'un axe, celui-ci doit être créé autour de cet axe. Rappelez-vous que le centre de tout objet doit être en 0 selon X, 0 selon Y et 0 selon Z.

Le code suivant va créer la pyramide autour d'un axe central. Le sommet de la pyramide est à une distance de 1 du centre tout comme la base de la pyramide. Le sommet est au milieu du plan, les sommets de la base sont à une distance de 1 du centre.

Remarquez que tous les triangles sont dessinés dans le sens trigonométrique. Ceci est important et sera expliqué dans un prochain tutoriel; pour l'instant, sachez simplement que c'est une bonne habitude de dessiner dans le sens horaire ou trigonométrique, mais que vous ne devriez pas mélanger les deux, à moins d'avoir de solides arguments.

On commence par dessiner la face avant. Puisque toutes les faces partagent le sommet supérieur, on va le dessiner en rouge sur tous les triangles. La couleur des points du bas sera alternée. La face avant aura un point gauche vert et un point droit bleu. Puis le triangle sur le côté droit aura un point gauche bleu et un point droit vert. En alternant les deux couleurs du bas sur chaque face, on aura un point commun au bas de chaque face.

Le rendu de la première face de la pyramide

glColor3f(1.0f,0.0f,0.0f);      // Rouge
glVertex3f( 0.0f, 1.0f, 0.0f);  // Haut du triangle de face
glColor3f(0.0f,1.0f,0.0f);      // Vert
glVertex3f(-1.0f,-1.0f, 1.0f);  // Bas gauche du triangle de face
glColor3f(0.0f,0.0f,1.0f);      // Bleu
glVertex3f( 1.0f,-1.0f, 1.0f);  // Bas droit du triangle de face

Maintenant, au tour de la face droite. Remarquez que les deux points du bas sont dessinés à une distance de 1 à la droite du centre, et le sommet est dessiné à une distance de 1 sur l'axe des y, et au milieu de l'axe des x, ce qui incline la face depuis le point central en haut vers le coin droit du bas de l'écran.

Remarquez que le point gauche est cette fois-ci dessiné en bleu. De cette manière, il sera de la même couleur que le coin droit de la face avant. Ainsi on aura un dégradé de bleu depuis ce coin vers la face avant et vers celle de droite.

Remarquez aussi que les trois faces restantes sont incluses dans le même glBegin(GL_TRIANGLES) et glEnd() que la première face. Puisque nous faisons cet objet entièrement avec des triangles, OpenGL saura que chaque triplet de points que nous tracerons définira un triangle. Une fois que trois points sont tracés, s'il y a trois points suivants, il considèrera qu'il y a un nouveau triangle à tracer. Si vous ajoutez q points au lieu de trois, OpenGL va tracer les trois premiers comme un triangle et considèrera le 4e comme le départ d'un nouveau triangle. Il ne dessinera pas un quadrilatère, donc soyez sûr que vous n'ajoutez pas de points supplémentaires par accident.

Le rendu de la deuxième face de la pyramide

glColor3f(1.0f,0.0f,0.0f);           // Rouge
glVertex3f( 0.0f, 1.0f, 0.0f);       // Haut du triangle (Droit)
glColor3f(0.0f,0.0f,1.0f);           // Bleu
glVertex3f( 1.0f,-1.0f, 1.0f);       // Gauche du triangle (Droit)
glColor3f(0.0f,1.0f,0.0f);           // Vert
glVertex3f( 1.0f,-1.0f, -1.0f);      // Droite du triangle (Droit)

Passons à la face arrière, avec à nouveau un changement de couleur. Le point gauche est vert puisque le coin commun avec la face droite est vert.

Le rendu de la troisième face de la pyramide

glColor3f(1.0f,0.0f,0.0f);      // Rouge
glVertex3f( 0.0f, 1.0f, 0.0f);  // Haut du triangle (Arrière)
glColor3f(0.0f,1.0f,0.0f);      // Vert
glVertex3f( 1.0f,-1.0f, -1.0f); // Gauche du triangle (Arrière)
glColor3f(0.0f,0.0f,1.0f);      // Bleu
glVertex3f(-1.0f,-1.0f, -1.0f); // Droite du triangle (Arrière)

Enfin, nous dessinons la face gauche. On échange les couleurs une dernière fois. Le point gauche est bleu et correspond au point droit de la face arrière. Le point droit est vert et correspond au point gauche de la face avant.

Nous avons fini de dessiner la pyramide. Comme celle-ci ne tourne que selon l'axe Y, nous ne verrons jamais la face du dessous, donc il n'y a pas besoin de dessiner cette face de la pyramide. Si vous désirez tester, essayez d'ajouter un fond en utilisant un quadrilatère, puis tournez sur l'axe X pour voir si vous l'avez fait correctement. Assurez-vous que les couleurs utilisées à chaque coin du quadrilatère correspondent aux couleurs utilisées aux quatre sommets inférieurs de la pyramide.

Le rendu de la quatrième face de la pyramide

glColor3f(1.0f,0.0f,0.0f);       // Rouge
glVertex3f( 0.0f, 1.0f, 0.0f);   // Haut du triangle (Gauche)
glColor3f(0.0f,0.0f,1.0f);       // Bleu
glVertex3f(-1.0f,-1.0f,-1.0f);   // Gauche du triangle (Gauche)
glColor3f(0.0f,1.0f,0.0f);       // Vert
glVertex3f(-1.0f,-1.0f, 1.0f);   // Droite du triangle (Gauche)
glEnd();                            // Fin du dessin de la pyramide

Maintenant, nous allons dessiner le cube. Il est constitué de six quads. Chacun des quads est dessiné dans le sens trigonométrique, ce qui signifie que le premier point sera le point en haut à droite, puis le point en haut à gauche, le point en bas à gauche et enfin le point en bas à droite. Lorsque nous dessinerons la face arrière, il semblera que nous dessinons dans le sens horaire, mais rappelez-vous que si nous étions derrière le cube en le regardant, le côté gauche est en fait le vrai côté droit, et inversement.

Remarquez que nous plaçons le cube un peu plus loin dans l'écran dans cette leçon. Ainsi, la taille du cube apparaîtra plus proche de celle de la pyramide. Si elle n'était déplacée que de six unités dans l'écran, elle apparaîtrait bien plus grande que la pyramide, et une partie pourrait être rognée par les côtés de l'écran. Vous pouvez modifier ce paramètre pour voir son influence sur le déplacement et la taille du cube. Ceci est dû à la perspective. Les objets à une certaine distance doivent apparaître plus petits.

Le début du rendu du cube

glLoadIdentity();
glTranslatef(1.5f,0.0f,-7.0f);    // Déplacement à droite dans l'écran
glRotatef(rquad,1.0f,1.0f,1.0f);  // Tourne le cube selon X, Y & Z
glBegin(GL_QUADS);                // Début du dessin du cube

Nous commençons par dessiner le dessus du cube. On va monter d'une unité depuis le centre du cube. Remarquez que l'axe Y est toujours à 1. Nous allons maintenant dessiner un quadrilatère sur le plan Z, vers l'intérieur de l'écran. Nous commençons par tracer le point en haut à droite sur la face supérieure du cube. Ce point sera à une unité vers la droite et une unité vers l'intérieur de l'écran. Le second point sera à une unité vers la gauche et vers l'intérieur de l'écran. Maintenant, nous devons dessiner le bas du quadrilatère vers l'extérieur. À cet effet, à la place de prendre une unité vers l'intérieur de l'écran, on prendra une unité vers l'extérieur. Logique, non ?

Le rendu de la première face du cube

glColor3f(0.0f,1.0f,0.0f);      // Couleur verte
glVertex3f( 1.0f, 1.0f,-1.0f);  // Haut droit du quadrilatere (Haut)
glVertex3f(-1.0f, 1.0f,-1.0f);  // Haut gauche du quadrilatere (Haut)
glVertex3f(-1.0f, 1.0f, 1.0f);  // Bas gauche du quadrilatere (Haut)
glVertex3f( 1.0f, 1.0f, 1.0f);  // Bas droit du quadrilatere (Haut)

La face du dessous est dessinée exactement de la même manière, mais comme c'est la face du dessous, elle est dessinée une unité vers le bas depuis le centre du cube. Remarquez que la valeur en Y est toujours égale à -1. Si nous étions sous le cube, regardant vers le quadrilatère qui constitue le fond, vous remarqueriez que le sommet en haut à droite est le sommet le plus proche de la personne qui regarde, donc à la place de dessiner les points éloignés en premier, nous dessinons le point le plus proche pour commencer, puis le point à gauche le plus proche puis nous rentrons dans l'écran pour dessiner les points restants.

Si vous ne faites vraiment pas attention à l'ordre dans lequel le polygone est dessiné - horaire ou trigonométrique -, vous copiez simplement le même code pour le quadrilatère du dessus, vous le déplacez en y=-1 et cela marchera, mais ignorer l'ordre du quadrilatère peut causer des résultats bizarres une fois que vous voulez faire des choses plus exotiques telles que l'application de textures.

Le rendu de la deuxième face du cube

glColor3f(1.0f,0.5f,0.0f);      // Couleur orange
glVertex3f( 1.0f,-1.0f, 1.0f);  // Haut droit du quadrilatere (Bas)
glVertex3f(-1.0f,-1.0f, 1.0f);  // Haut gauche du quadrilatere (Bas)
glVertex3f(-1.0f,-1.0f,-1.0f);  // Bas gauche du quadrilatere (Bas)
glVertex3f( 1.0f,-1.0f,-1.0f);  // Bas droit du quadrilatere (Bas)

Maintenant, nous allons tracer le quadrilatère de la face avant. On se déplace d'une unité vers l'écran depuis le centre pour tracer cette face. Remarquez que la valeur selon Z vaut toujours 1. Dans la pyramide, cela n'était pas toujours le cas. Au sommet, il valait 0. Si vous essayez de changer la valeur en la mettant à 0, vous constaterez que le point que vous avez bougé se déplace dans l'écran. Ce n'est pas vraiment ce que nous voudrions faire maintenant.

Le rendu de la troisième face du cube

glColor3f(1.0f,0.0f,0.0f);       // Couleur rouge
glVertex3f( 1.0f, 1.0f, 1.0f);   // Haut droit du quadrilatere (Avant)
glVertex3f(-1.0f, 1.0f, 1.0f);   // Haut gauche du quadrilatere (Avant)
glVertex3f(-1.0f,-1.0f, 1.0f);   // Bas gauche du quadrilatere (Avant)
glVertex3f( 1.0f,-1.0f, 1.0f);   // Bas droit du quadrilatere (Avant)

La face arrière est un quadrilatère identique à la face avant, mais placé plus à l'arrière de l'écran. Remarquez que la valeur selon Z vaut maintenant toujours -1. De même, l'ordre des sommets du quadrilatère est inversé.

Le rendu de la troisième face du cube

glColor3f(1.0f,1.0f,0.0f);      // Couleur jaune
glVertex3f( 1.0f,-1.0f,-1.0f);  // Haut droit du quadrilatere (Arriere)
glVertex3f(-1.0f,-1.0f,-1.0f);  // Haut gauche du quadrilatere (Arriere)
glVertex3f(-1.0f, 1.0f,-1.0f);  // Bas gauche du quadrilatere (Arriere)
glVertex3f( 1.0f, 1.0f,-1.0f);  // Bas droit du quadrilatere (Arriere)

Maintenant, il ne reste plus que deux autres quads à dessiner et nous aurons fini. Comme d'habitude, vous noterez que la valeur sur un axe est identique pour tous les points. Ici, ce sera sur l'axe X que les valeurs vaudront toujours -1. Ceci s'explique par le fait qu'on dessine à gauche du centre puisque ce sera la face gauche.

Le rendu de la quatrième face du cube

glColor3f(0.0f,0.0f,1.0f);      // Couleur bleue
glVertex3f(-1.0f, 1.0f, 1.0f);  // Haut droit du quadrilatere (Gauche)
glVertex3f(-1.0f, 1.0f,-1.0f);  // Haut gauche du quadrilatere (Gauche)
glVertex3f(-1.0f,-1.0f,-1.0f);  // Bas gauche du quadrilatere (Gauche)
glVertex3f(-1.0f,-1.0f, 1.0f);  // Bas droit du quadrilatere (Gauche)

Ceci est la dernière face pour compléter le cube. La valeur sur l'axe X est toujours de 1. Le dessin se fait dans le sens trigonométrique. Si vous voulez, vous pouvez laisser de côté cette face et faire du cube une boîte

Si vous vous sentez prêt à expérimenter, vous pouvez essayer de changer la couleur des coins sur le cube pour faire des mélanges comme dans le cas de la pyramide. Vous pouvez voir un tel exemple en téléchargeant la première démo OpenGL d'Evil depuis la page web de nehe. Lancez-la et appuyez sur TAB. Vous verrez un joli cube colorié avec des couleurs défilant sur les faces.

Le rendu de la cinquième face du cube

glColor3f(1.0f,0.0f,1.0f);      // Couleur violette
glVertex3f( 1.0f, 1.0f,-1.0f);  // Haut droit du quadrilatere (Droite)
glVertex3f( 1.0f, 1.0f, 1.0f);  // Haut gauche du quadrilatere (Droite)
glVertex3f( 1.0f,-1.0f, 1.0f);  // Bas gauche du quadrilatere (Droite)
glVertex3f( 1.0f,-1.0f,-1.0f);  // Bas droit du quadrilatere (Droite)
glEnd();                           // Fin du dessin des quadrilateres

rtri+=0.2f;                        // Incremente la variable de la rotation du triangle
rquad-=0.15f;                      // Decremente la variable de rotation des quads

return TRUE;                       // On continue
}

À la fin de ce tutoriel, vous devriez avoir une meilleure compréhension de la création des objets en 3D. Vous devez imaginer l'écran OpenGL comme une immense pièce sur un papier graphe, avec plusieurs couches transparentes derrière, presque tel un cube géant constitué de points. Certains des points bougent de gauche à droite, d'autres de haut en bas, et d'autres s'éloignent dans le cube. Si vous pouvez visualiser la profondeur dans l'écran, vous ne devriez pas avoir de problème pour créer de nouveaux objets 3D.

Si vous avez des difficultés à comprendre l'espace 3D, ne soyez pas frustrés, cela peut se révéler difficile à saisir correctement dès le départ. Un objet tel que le cube est un bon exemple pour apprendre. Si vous avez remarqué, la face arrière est dessinée exactement comme la face avant, elle n'est juste plus dans l'écran. Jouez un peu avec le code, et si vous ne comprenez vraiment pas, envoyez-moi un email et j'essaierai de répondre à vos questions.

Jeff Molofee ( NeHe )

III - Téléchargements

Compte tenu du nombre de versions de codes sources pour les tutoriels nehe, nous les laissons en anglais. En principe, si vous avez compris le code présenté dans ce tutoriel (et les tutoriels antérieurs), vous n'aurez pas de mal à le comprendre :

- ASM (Conversion par Foolman)

- BeOS (Conversion par Rene Manqueros)

- Borland C++ Builder 6 (Conversion par Christian Kindahl)

- C# (Conversion par Sabine Felsinger)

- Code Warrior 5.3 (Conversion par Scott Lupton)

- CygWin (Conversion par Stephan Ferraro)

- D (Conversion par Familia Pineda Garcia)

- Delphi (Conversion par Michal Tucek)

- Dev C++ (Conversion par Dan)

- Euphoria (Conversion par Evan Marshall)

- Game GLUT (Conversion par Milikas Anastasios)

- GLUT (Conversion par Andy Restad)

- Irix (Conversion par Lakmal Gunasekara)

- Java (Conversion par Jeff Kirby)

- Java/SWT (Conversion par Victor Gonzalez)

- Jedi-SDL (Conversion par Dominique Louis)

- JOGL (Conversion par Kevin J. Duling)

- LCC Win32 (Conversion par Robert Wishlaw)

- Linux (Conversion par Richard Campbell)

- Linux GLX (Conversion par Mihael Vrbanec)

- Linux SDL (Conversion par Ti Leggett)

- LWJGL (Conversion par Mark Bernard)

- Mac OS (Conversion par Anthony Parker)

- Mac OS X/Cocoa (Conversion par Bryan Blackburn)

- MASM (Conversion par Nico (Scalp))

- Pelles C (Conversion par Pelle Orinius)

- Perl (Conversion par Cora Hussey)

- Power Basic (Conversion par Angus Law)

- Python (Conversion par Tony Colston)

- REALBasic (Conversion par Thomas J. Cunningham)

- Scheme (Conversion par Jon DuBois)

- Solaris (Conversion par Lakmal Gunasekara)

- VB.NET CsGL (Conversion par X)

- Visual Basic (Conversion par Ross Dawson)

- Visual Fortran (Conversion par Jean-Philippe Perois)

- Visual Studio

- Visual Studio NET (Conversion par Grant James)

IV - Remerciements

Merci à fearyourself, jc_cornic et à khayyam90 pour leur relecture.

V - Liens

Sommaire

Tutoriel précédent : Rotations

Tutoriel prochain : Textures