La 3D avec OpenGL
Voir en 3D
- Nécessité de réaliser de nombreuses opérations
- Rotations, translations, mise à l'échelle, projection, clipping,
changements de repère, etc...
- Notion de "caméra virtuelle"

Rappel : une matrice 4x4 peut
- Spécifier un repère (3 premières colonnes = vecteurs
directeurs, dernière colonne = position du centre)
- Effectuer un changement de repère : P(camera) = Mobjet_camera .
P(objet)
- Effectuer une projection planaire

- Encoder une transformation affine : rotation, translation ou mise à
l'échelle 3D.

Pipe line OpenGL

Matrice MODELVIEW
- Passe les coordonnées des objets à dessiner (modèles)
dans le repère de la caméra. Définit un repère
!
- La position de la caméra est en général (0,0,0) donc
la matrice MODELVIEW représente la position où sera dessiné
le prochain objet.
Matrice PROJECTION
- Clippe les coordonnées des points et les projette
Division perspective
- Division par la coordonnée homogène w pour obtenir des coordonnées
normalisées
Viewport transformation
- Passage en pixel pour dessin dans une partie d'une fenêtre graphique
(viewport)
Avec OpenGL comment on manipule tout ça ?
- Il existe une "matrice courante" que l'on spécifie avec
la commande glMatrixMode(GL_MODELVIEW) ou glMatrixMode(GL_PROJECTION)
- En général on travaille tout le temps sur la matrice MODELVIEW
sauf lorsqu'on doit modifier les paramètres intrinsèques de
la caméra (focale, taille du viewport, etc...).
...
glMatrixMode(GL_PERSPECTIVE);
glLoadIdentity();
gluPerspective(myFovy, 1.0, myNear, myFar);
glViewport(0, 0, 400, 400);
glMatrixMode(GL_MODELVIEW);
...
- REMARQUE : à l'aide de la fonction glViewport() on peut dessiner
la même scène à plusieurs endroits sur la fenêtre
graphique.
- Attention : pour déplacer la caméra on ne travaille pas sur
la matrice PROJECTION, puisque la matrice qui encode le changement de repère
modele vers caméra est la MODELVIEW.
Comment changer la valeur de la matrice courante ?
- Eh bien, gluLookAt(...) affecte la matrice courante ! Elle la remplace
carrément ! Vous voyez pourquoi ?
- Autres fonctions : glRotate(), glTranslate(), glScale(), glMultMatrix(),
glLoadMatrix(), glLoadIdentity()
- Remarque : une matrice = un vecteur de 16 valeurs (un tableau)
- Ordre des transformations :

On applique les transformations de droite à gauche.
ATTENTION : si vous avez fait un glScale() toutes les transformations suivantes
se feront avec les nouvelles unités !
Comment donner l'illusion que la caméra se déplace ?
- Pour donner l'illusion que la caméra se déplace, on se place
dans MODELVIEW et on utilise la fonction

En réalité la caméra reste tout le temps immobile ! C'est
toute la scène qui bouge !

glMatrixMode(GL_MODELVIEW);
...
glTranslatef(0.0, 0.0, -5.0);

- Penser au produit vectoriel pour orienter un repère !
On empile des matrices !
- Avec OpenGL : deux piles une grosse pour les matrices de type MODELVIEW
et une petite pour les matrices de type PROJECTION

- Utile pour représenter des modèles hiérarchisés
ou encore pour dessiner des objets sans afefcter les autres, pour faire des
animations, etc...
- On empile et on dépile avec les fonctions glPushMatrix() et glPopMatrix()

- La matrice courante est toujours celle en haut de la pile.
- On manipule dans 99% des cas la pile MODELVIEW.
- Cas où on manipule la pile projection = par exemple pour afficher
une aide en projection //
Plans de clipping additionnels
- On peut ajouter jusqu'à 6 plans de clipping additionels
- Un plan = Ax+By+Cz+D = 0, coordonées caméra
- void glClipPlane(GLenum plane, const GLdouble *equation); définit
un plan de clipping.
double plan1 = {1.0, 1.0, 0.0, 0.0};
glClipPlane(0, plan1);
glEnable(GL_CLIP_PLANE0);
Exemple de plan de clipping
void display(void) {
GLdouble eqn[4] = {0.0, 1.0, 0.0, 0.0}; /* y < 0 */
GLdouble eqn2[4] = {1.0, 0.0, 0.0, 0.0}; /* x < 0 */
glClear(GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glPushMatrix();
glTranslatef (0.0, 0.0, -5.0);
glClipPlane (GL_CLIP_PLANE0, eqn);
glEnable (GL_CLIP_PLANE0);
glClipPlane (GL_CLIP_PLANE1, eqn2);
glEnable (GL_CLIP_PLANE1);
glRotatef (90.0, 1.0, 0.0, 0.0);
glutWireSphere(1.0);
glPopMatrix();
glFlush();
}
Quelques exemples d'objets hiérarchisés
glPushMatrix();
glutWireSphere(1.0); /* draw sun */
glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);
glTranslatef (2.0, 0.0, 0.0);
glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);
glutWireSphere(0.2); /* draw smaller planet */
glPopMatrix();
Quelques exemples d'objets hiérarchisés (2)
glTranslatef (-1.0, 0.0, 0.0);
glRotatef ((GLfloat) shoulder_angle, 0.0, 0.0, 1.0);
glTranslatef (1.0, 0.0, 0.0);
glutWireBox(2.0, 0.4, 1.0);
glTranslatef (1.0, 0.0, 0.0);
glRotatef ((GLfloat) elbow_angle, 0.0, 0.0, 1.0);
glTranslatef (1.0, 0.0, 0.0);
glutWireBox(2.0, 0.4, 1.0);
etc...