Programmer en C++
OpenGL - Premier dessin

1. Explication du code nécessaire

C'est dans la fonction "renduScene()" que nous allons maintenant placer notre code destiné à afficher notre premier dessin : un triangle. A partir de maintenant nous utiliserons des fonctions de la bibliothèque OpenGL, qui ont la capacité d'agir directement avec le GPU (Graphic Processeur Unit) de la carte graphique. Par la suite, cette façon de procéder, va nous procurer un gain extraordinaire de vitesse d'animation, ou nous permettre de complexifier les objets animés tout en gardant une excellente fluidité de mouvements.

La première fonction que nous découvrons ici est :

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Cette fonction permet de vider les tampons (zone mémoire de la carte graphique) qui lui sont transmis en arguments. Nous lui en donnons deux ici :
• GL_COLOR_BUFFER_BIT qui est le tampon pour les dessins, et
• GL_DEPTH_BUFFER_BIT qui est le tampon pour la profondeur des dessins (axe z pour la 3D).

Les dessins se font en plaçant un point, ou un groupe de points à l'aide de fonction(s) :

void glVertex3f(float x, float y, float z);

Chaque point est défini par 3 coordonnées (x, y, z). On est donc en 3D ! Par défaut z = 0 si sa valeur est omise.

L'envoi d'un point ou d'un groupe de points se fait en encadrant le ou les points avec une fonction glBegin(), et glEnd(). Pour une surface, par exemple un triangle, nous écrivons :

glBegin(GL_TRIANGLES);
                glVertex3f(-0.5, -0.5, 0.0);
                glVertex3f(0.5, 0.0, 0.0);
                glVertex3f(0.0, 0.5, 0.0);
glEnd();

Nous avons donné l'argument GL_TRIANGLES à la première fonction "glBegin()". On peut en donner beaucoup d'autres : GL_POINTS, GL_LINES, GL_POLYGON, etc. En savoir plus sur "glBegin()"
Le nombre de point(s) à fournir dépend donc de l'argument utilisé.

Pour terminer nous utilisons la fonction :

glutSwapBuffers();

Elle permet de faire basculer l'affichage d'une zone mémoire sur laquelle on dessine chaque objet, vers la zone mémoire qui affiche le contenu de la fenêtre. Celà évite les scintillements provoqués par l'affichage successif de chaque objet.

2. Une fonction renduScene() qui affiche un triangle

void renduScene()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBegin(GL_TRIANGLES);
                glVertex3f(-0.5, -0.5, 0.0);
                glVertex3f(0.5, 0.0, 0.0);
                glVertex3f(0.0, 0.5, 0.0);
    glEnd();
    glutSwapBuffers();
}

Comparons maintenant notre dessin avec celui affiché dans la fenêtre.

Si la zone de rendue de la fenêtre n'est pas choisie carrée, alors le dessin est déformé (étiré sur l'axe Ox, ou l'axe Oy).
Le coin supérieur gauche de la zone de rendue a pour coordonnées (-1, 1) alors que le coin inférieur droit de cette même zone a pour coordonnées (1, -1). C'est encore vrai si nous étirons la fenêtre avec la souris. Par conséquent déformer la fenêtre, déforme le dessin.

3. Un peu de couleur

Par défaut lorsque nous dessinons dans la fenêtre, le fond apparait en noir et les dessins en blanc. Est-il possible de mettre un peu de couleur ?
Oui tout simplement en ajoutant la fonction :

glClearColor(1.0, 0.8, 0.4, 1.0);

Cette fonction sera à mettre juste avant "glClear()", car "glClear()" ne fait pas qu'effacer la fenêtre, elle applique aussi la couleur définie par "glClearColor()" à toute la fenêtre. C'est donc la couleur du fond (ici un orangé).
Attention chaque couleur est définie de 0.0 mini à 1.0 maxi. Dans l'ordre, les paramètres sont comme d'habitude le rouge, le vert, et le bleu. Le dernier paramètre est la transparence (canal alpha) de 0.0 transparent à 1.0 opaque.

Très bien pour le fond, mais peut-on aussi colorier notre triangle ?
Bien sur avec la fonction :

glColor3f(1.0, 0.0, 0.0);

J'ai choisi ici un rouge pur.
La couleur est à placer entre glBegin() et glEnd(), et juste avant de définir les points. Voilà alors ce que ça donne :

Peut-on mettre une couleur différente par point ?
Oui en écrivant la nouvelle couleur avant de définir le point concerné
Voilà ce que nous obtenons avec le premier point en rouge, le second en bleu, et le dernier en vert. Observez comment le triangle apparait en couleurs dégradées à partir de chaque sommet.

4. Le code complet

#include <GL/glut.h>

void renduScene()
{
    glClearColor(1.0, 0.8, 0.4, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBegin(GL_TRIANGLES);
                glColor3f(1.0, 0.0, 0.0);     // De la couleur
                // Coordonnées des vertex (des points)
                glVertex3f(-0.5, -0.5, 0.0);
                glVertex3f(0.5, 0.0, 0.0);
                glVertex3f(0.0, 0.5, 0.0);
    glEnd();
    glutSwapBuffers();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(300, 200);
    glutCreateWindow("Fenetre avec freeglut");
    glutDisplayFunc(renduScene);

    glutMainLoop();

    return 0;
}