Programmer en C++
freeglut - Empêcher les déformations

1. Introduction

Nous avons remarqué au chapitre précédent que redimensionner la fenêtre pouvait conduire à une déformation de l'image qu'elle contient.
Nous allons voir dans cette partie comment s'affranchir de ce problème.

2. Modification de la fonction "main()"

Dans la fonction "main()" nous ajoutons la fonction :

glutReshapeFunc(changeDimensions);

Elle sera placée juste avant la fonction "glutMainLoop()". On aura donc maintenant :

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(300, 200);
    glutCreateWindow("Triangle a echelle variable");

    glutDisplayFunc(renduScene);
    glutReshapeFunc(changeDimensions);

    glutMainLoop();

    return 1;
}

3. La fonction "changeDimensions()"

Dans un premier temps, je vais donner l'intégralité du code, puis je reviendrai ensuite uniquement sur certaines parties que j'estime importante pour comprendre certains phénomènes. J'éviterai volontairement pour le moment tout ce qui touche au calcul matriciel dont le niveau est du domaine universitaire.

void changeDimensions(int w, int h)
{
    // On se protège d'une division par zéro, et on calcul le rapport W/H.
    // W = Width = Largeur de la fenêtre, h = hauteur de la fenêtre
    if(h == 0)
            h = 1;
    float rapportWsurH = 1.0 * w / h;

    // Choix d'une matrice de calcul pour la projection des points
    glMatrixMode(GL_PROJECTION);

    // Remplacement de la matrice actuelle par la matrice unité.
    glLoadIdentity();

    // Paramétrage de la fenêtre d'affichage
    glViewport(0, 0, w, h);

    // Paramétrage de l'observation, perspective, ...
    gluPerspective(45, rapportWsurH, 1, 50);

    // Retour à la vue initiale
    glMatrixMode(GL_MODELVIEW);
}

La première partie de la fonction "changeDimensions()" calcule le rapport de la largeur sur la hauteur de la fenêtre.
Je passe donc volontairement les fonctions concernant le calcul matriciel qui concerne les fonctions "glMatrixMode()", "glLoadIdentity()", et " glMatrixMode".

La première fonction que nous allons détailler est la suivante :

glViewport(0, 0, w, h);

Cette fonction permet de définir la surface qui sera utilisée pour le rendu dans la fenêtre. Elle prend quatre paramètres :
• Les deux premiers précisent les coordonnées x, et y du coin supérieur gauche de la zone d'affichage, et
• les deux derniers la largeur, puis la hauteur de cette zone.
On voit donc ici que nous sélectionnons la totalité de la fenêtre.

L'autre fonction que nous allons détailler est la plus importante à comprendre. En effet si vous lancez l'application telle que nous venons de la présenter, rien ne s'affiche !
Examinons cette fonction pour comprendre :

gluPerspective(45, rapportWsurH, 1, 50);

Les paramètres qui sont transmis à cette fonction sont dans l'ordre :
• L'angle du champ de vision (il est noté θ sur la fig.),
• le rapport largeur sur hauteur de la fenêtre (rapportWsurH),
• la distance du plan de sélection le plus proche, et
• la distance du plan de sélection le plus éloigné.

Voici la figure qui vous aidera à mieux comprendre cette partie :

Avec les valeurs saisies, nous avons le plan le plus proche à une distance de 1, et le plan le plus éloigné à une distance de 50.
Autrement dit, tout objet dessiné avec des valeurs z plus grande que -1, et plus petite que -50, n'apparaitra pas dans la zone de rendue.
C'est surement un peu confus, mais il faut savoir que les distances des plans par rapport à l'origine de l'observation en O, se compte positivement, alors que l'éloignement des objets se font ici négativement sur l'axe z.

Maintenant vous devez avoir compris pourquoi notre triangle dessiné au chapitre précédent ne peut pas apparaître.

Modifions les valeurs de z pour chaque vertex. On mettra par exemple z = - 2.0

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


Et voilà le travail ! Quelque soit les dimensions de notre fenêtre, notre triangle gardera toujours les mêmes proportions.