TD d`infographie n°1

publicité
TD d'introduction à la 3D n°1
Licence 3ème année Informatique
Apprendre à construire, voir & modéliser
Apprendre le principe de la modélisation d'objet, des
transformations et du positionnement de la caméra
A savoir 1 : le contexte d'une application interactive
Avant de se jeter dans le code, il est utile de bien comprendre les interactions entre chacun des
composants que nous allons utiliser.
OpenGL est ce qu'on appelle une Application Programming Interface (API). En tant que telle, elle
ne propose qu'une liste de fonctions et de types qui doivent respecter un comportement défini par la
spécification OpenGL (http://www.opengl.org/registry/). Pour pouvoir effectivement utiliser
OpenGL, il est nécessaire d'avoir une implantation d'OpenGL, c'est à dire une bibliothèque (fichier
en .dll sous Windows ou .so sous Linux) contenant du code compilé et implantant les fonctions
définies dans la spécification. Les implantations hardware d'OpenGL sont le plus souvent faites par
les fabricants de cartes graphiques (NVidia, ATI, ...). Elles se basent sur les drivers de la carte
graphique.
OpenGL est une API de rendu, c'est à dire qu'elle propose des fonctions uniquement destinées au
dessin 3D. Elle ne précise pas où elle doit dessiner (une fenêtre, une zone mémoire, un fichier, ...),
quel format de couleurs utiliser, etc. C'est donc à l'application de créer un contexte OpenGL qui
précisera ces détails. Pour cela on utilise la plupart du temps une autre API (SDL, glut...) qui fait
cela pour nous automatiquement.
Le schéma suivant résume ces interactions:
Dans notre cas nous allons utiliser la bibliothèque libg2x qui, elle même, est fondée sur glut. C'est
cette API qui crée un contexte au moment de la création d'une fenêtre. De plus, nous n'aborderons
pas la programmation OpenGL (fait en master) dans le détail mais exploiterons des « surcouches »
plus pratique pour concevoir notre scène 3D. L'objectif étant de se familliariser avec les notions de
modélisation 3D et de rendu.
A savoir 2 : les mathématiques de la 3D
Pour réaliser une scène 3D et l'illuminer on a besoin de concevoir informatique et donc
mathématiquement les objets de la scène. Il faut donc aborder, un peu, les mathématiques et plus
particulièrement les transformations mais rassurons nous, rien de bien sorcier là dedans.
Un point dans l'espace se caractérise par ses 3 coordonnées x, y et z. De même une direction (ou un
déplacement), appelé aussi vecteur, peut se quantifier par ces 3 coordonnées x, y et z (déplacement
sur chaque axe). Mais, afin de simplifier les transformations des points & des vecteurs, on leur
rajoute fréquemment une quatrième coordonnée : la coordonnée homogène. Nous verrons en Master
pourquoi cela est nécessaire. Le principe est simple (pour nous) : la quatrième coordonnée vaut 1
pour les points, et 0 pour les vecteurs.
Maintenant à l'aide de ses 4 coordonnées (x,y,z,w) on peut appliquer des transformations que l'on
définit sous forme de matrice 4x4. L'avantage est que l'on peut appliquer ces matrices indifférement
pour un point ou un vecteur. Les transformations se codent donc, en informatique 3D, sous la forme
de matrice 4x4. Voici l'ensemble des transformations affines standard :
* La translation (définie sur les 3 axes x,y,z)
* La rotation qui en 3D dépend d'un angle et d'un axe (vecteur)
* L'homothétie (aggrandissement, réduction) qui peut se faire sur les 3 axes
Toutes ces transformations se définissent par des matrices 4x4. L'intérêt c'est qu'en multipliant
ensemble ces matrices, on compose les transformations.
A savoir 3 : les couleurs
En fait en infographie 3D (et 2D), on définit fréquemment les couleurs par 3 valeurs pour le rouge,
le vert et le bleu. En 3D plus particulièrement, ces valeurs sont des flotants compris entre 0 et 1.
Ainsi pour définir la couleur rouge pure, la valeur de la couleur est (1,0,0).
Exercice 1 : Compilation & Prise en main...
Nous allons partir d'un programme « chien, mouton, loup » résumant ce que vous avez fait
précédemment. Nous passerons de la vision 2D de cet univers à une vue 3D.
1. Téléchargez sur le site Internet http://igm.univ-mlv.fr/~biri/ , section Enseignement, L3info,
l'archive du code.
2. Allez dans le répertoire libg2x, et lancez la commande qmake (dans un terminal). Puis
lancez make. La bibliothèque devrait se compiler. Retournez dans le répertoire parent et
lancez la commande install_libgXd.sh. Puis lancez la compilation avec un make dans un
nouveau terminal.
3. Exécutez le programme créé. Vous devriez voir une « scène » constituée d'un repère et d'un
quadrilatère vert bizarrement placé (le sol). Certains touches agissent :
Touche 'i'
Bascule entre notre vue 3D et la vue de la scène 2D du programme des
« chiens, moutons, loups ».
Barre d'espace
Déclenche l'animation des agents (chien, moutons & loups).
Touche 'f'
(en mode 3D). Zoom sur la partie centrale de la scène (pour affiner le
dessin de son chien – voir exercice 4).
4. En cliquant sur le bouton de gauche, prenez une image de votre environnement...
5. Étudiez spécifiquement le fichier main.cpp et plus particulièrement les fonctions initGL,
drawXXX, Dessin, keyPressXXX, et le main.
Exercice 2 : Ma première transformation
Pour utiliser des matrices, regardez le fichiers matrix4d.hpp dans le répertoire tools.
Nous allons commencer par effectuer une première transformation qui va permettre de mettre le sol
au centre du repère. Trouvez les transformations (une rotation & une translation) permettant de
positionner le centre du sol au centre du repère et sur le plan (xy). Le sol doit, à la fin, être à la
même position que le plan marron quand vous appuyer sur la touche 'i'.
Attention l'ordre des transformations est important. Pour vous en convaincre, inversez l'ordre de vos
transformation et observez le résultat.
Exercice 3 : Pour composer pleins de transformation
Les transformations d'objets dans une scène 3D peuvent s'effectuer grâce à une pile de matrice. La
matrice située en haut de la pile représente en général une composition (accumulation) de
nombreuses transformations. En effet chaque transformation que l'on ajoute modifie la matrice de
haut de pile. Or on va faire en sorte que cette matrice s'applique à toutes les coordonnées des points.
L'intérêt d'avoir une pile de matrice (et non une matrice seule), c'est que l'on peut sauvegarder à tout
moment l'état des transformations. En effet, chaque transformation change le repère initial (celui
que vous voyez quand vous lancez le programme). Donc chaque niveau de la pile peut représenter
un repère différent ce qui sera bien pratique pour construire des scènes complexes. Pour
sauvegarder l'état de la pile de matrice, et donc le repère courant, on utilise un pushMatrix. Pour
détruire les transformations courantes, on utilise un popMatrix. D'autres fonctions permettent en
général d'appliquer une translation, une rotation ou une homothétie à la matrice de haut de pile, et
donc de changer le repère courant.
L'intérêt de changer le repère courant c'est que c'est celui qui est utilisé pour le dessin final. Ainsi,
pour le moment, le dessin du « chien » (lancé par l'instruction dog->draw ) entraîne le dessin d'un
cube centré sur l'origine (et donc coupé en deux par le sol, appuyez par 'f' pour voir en détail).
1. Étudiez, dans le répertoire tools, le fichier MatrixStack.hpp. Il contient toutes les
fonctions dont vous avez besoin pour manipuler le repère courant.
2. Modifiez la fonction drawDog afin de
1. Le déplacer le long de l'axe z pour qu'il ne soit plus coupé en 2 par le plan.
2. Le faire bouger le long d'un cercle de rayon 10 autour du centre de la scene et autour de
l'axe z.
Pour ce faire, utilisez la pile de matrice appelée modelviewStack (variable globale), le push
& le pop afin de détruire les transformations une fois le sol dessiné.
Exercice 4 : Bouger la caméra !
Pour l'instant notre point de vue est fixe, c'est pénible…
L'application est prévue pour réagir aux touches 'z','s','q','d' (les gamers auront reconnu) ainsi que 'a'
et 'e'. On va faire en sorte que la caméra (le point de vue), orbite autour du centre de la scène
comme illustré sur ces figures :
Concept de caméra orbitale avec sa position
(camera) et son point visé (centre)
Position de la caméra avec les arguments de
position r, théta et phy
En effet, la caméra dans notre code est défini, pour le moment par sa position et le point qu'elle
« vise » (noté centre dans la figure ci-dessus à gauche) ainsi qu'un vecteur up dont on ne s'occupera
pas. La position de la caméra est donc située sur une (demi) sphère de rayon 'r' (noté rayon dans le
code source donné), faisant un angle phy (noté angle_phy dans le code) avec le plan (xy) et un
angle théta (noté angle_theta dans le code) avec l'axe x.
1. Trouvez les formules permettant de calculer les coordonnées x, y et z de la caméra à l'aide
des paramètres r, théta et phy.
2. Implémentez ces formules pour fixer la position de la caméra dans la fonction Dessin.
3. Implémentez les fonctions keyPressZoomXX et keyPressPanXX dans le fichier main.cpp
afin que les touches 'z','s' change le zoom, 'q','d' change l'angle théta et 'a','e' l'angle phy.
Exercice 5: Il y a des obstacles !
Nous allons maintenant transformer les cercles de la version 2d en cylindre de hauteur variable à la
même position. Vous récupérerez les coordonnées des cercles grâce au code préexistant (voir la
variable Circle dans main.cpp & le fichier circle.cpp.
1. Étudiez la fonction initGL pour voir comment est créé une forme de base et voir comment
les objets sont affichés. Regarder dans le fichier tools/basic_mesh.hpp les formes de
bases à votre disposition.
2. Dessinez un cylindre au centre de la scène.
3. Grâce à des transformations, afficher le 1er cylindre (du tableau Circle) à sa bonne place.
4. Dessinez tous les cylindres. Pour ce faire, n'utilisez qu'un seul objet cylindre.
Exercice 6: Dessine moi un chien !
Pour l'instant notre chien est un simple cube centré sur l'origine. Il faut changer cela. Les formes de
base comme les cubes peuvent être dupliquées à loisir sans avoir forcément à redéfinir un nouvel
objet (comme vu précédemment). Il suffit en effet de le dessiner dans un nouveau repère.
Concevez un modèle de chien de votre choix avec les formes de base à votre disposition (cube,
cone, cylindre, sphere). Elles sont dans le fichier tools/basic_mesh.hpp.
Téléchargement