Warning: Declaration of MainMenu::Show($MaxLevel) should be compatible with MenuItem::Show($Level = 0) in /var/www/html/evasion/people/Antoine.Bouthors/common.php on line 156

Warning: Declaration of MainMenu::FindMe($Path, $Level) should be compatible with MenuItem::FindMe($Path) in /var/www/html/evasion/people/Antoine.Bouthors/common.php on line 167
OpenGL : les bases
 

OpenGL : les bases

Ce troisi�me volet s'inscrit directement dans la continuit� du second, et il sera le m�me que vous utilisiez glut ou non. Nous allons �tudier les primitives et les matrices en nous appuyant sur le tutorial pr�c�dent. Reprenez donc le projet que nous avions commenc�, et qui affichait un magnifique triangle blanc.

Bon, on va commencer par le dessin en OpenGL. Pour dessiner, c'est hyper simple, et on peut faire n'importe quoi. Comme vous le savez s�rement si vous avez l�g�rement touch� � la 3D, TOUS les objet sont en fait une association d'�lements de base : ce sont des faces orgranis�es dans un certain ordre dans l'espace, qui repr�sentent l'objet. Chaque face peut �tre d�conpos�e en une s�rie de facettes triangulaires.

Ainsi, un rectangle est en fait constitu� de deux triangles cons�cutifs :

Ces triangles sont eux-m�me compos�s de 3 cot�s, ou 3 lignes, et de 3 points (ou vertex) qui d�finissent les extr�mit�s de ces segments. Ces �l�ments (points, lignes, triangles) sont aussi appel�s primitives. OpenGL est bas� sur le principe des primitives, c'est-�-dire que pour dessiner un objet, il faut dessiner toutes ses primitives (ca parait logique). Et pour cela, on utilise des fonctions tr�s simples d'utilistation et permettant des dessins tr�s pouss�s, puisque gr�ce � ces fonctions, on peut dessiner quasiment tout.
Passons maintenant � la pratique : comment dessiner un �l�ment primitif ? H� bien vous l'aurez s�rement devin� en lisant le code d'exemple du triangle : on appelle glBegin() avec comme param�tre l'�l�ment, on lui envoie les coordonn�es des vecteurs-cl�s via glVertex(), et on tremine avec glEnd(). Ultra simple, non ?
Notez que vous ne verrez rien si vous n'applez pas SwapBuffers(DC). Pourquoi ? Parce qu'on utilise une technique appel�e double-buffering, qui consiste � afficher une image pendant que l'on calcule l'autre, et lorsque celle-ci est termin�e, on �change les deux. Donc si on enl�ve SwapBuffers(DC), on verra toujours un �cran vide, tandis qu'on dessinera dans un �cran non visible. Si vous travaillez en mode simple-buffering (changez l'option dans SetupPixelFormat() pour les windows-lover, et dans glutInit() pour les glut-lover), il faut remplacer SwapBuffers() par glFlush(). Mais c'est stupide de n'utiliser qu'un seul buffer, car la construction de l'image est alors visible, ce qui provoque un effet de scintillement.
Voyons maintenant ce que l'on peut dessiner � part des triangles :

Param�tre transmis � glBegin Description Exemple
GL_POINTS Dessine un point pour chaque vertex transmis.
GL_LINES Dessine des lignes. Le point n d�fini le d�but d'une ligne et le point n+1 la fin de la ligne.
GL_LINE_STRIP Dessine un groupe de lignes connect�es, formant une chaine partant du premier vertex et s'arr�tant au deriner.
GL_LINE_LOOP M�me chose que GL_LINE_STRIP, mais en revenant au premier vertex � la fin.
GL_TRIANGLES Chaque triplet de vertex constitue un triangle
GL_TRIANGLE_STRIP Un triangle est d�fini pour chaque vertex pr�sent� apr�s les deux premiers
GL_TRIANGLE_FAN M�me chose que GL_TRIANGLE_STRIP, sauf que le premier vertex de chaque triangle est toujours le n�1
GL_QUADS Chaque quadruplet de vertex d�finit un quadrilat�re (compos� de 2 triangles)
GL_QUAD_STRIP Chaque couple de vertex pr�sent� apr�s la premi�re paire d�finit un quadrilat�re (attention � l'ordre des points)
GL_POLYGON Dessine un polygone convexe

Remarque : les lignes rouges et les num�ros sur les exemples servent seulement � montrer comment sont dessin�s les primitives, mais ne sont pas visibles en r�alit�.

Tout-�-l'heure, j'ai parl� de glVertex(), et pourtant dans mon exemple il y a �crit glVertex2d(). Pourquoi ? H� bien parce qu'en fait il y a une multitude de fonctions pour dessiner des sommets. En fait, on appelle toujours la fonction glVertexxy[v](), o� :

  • x d�finit le nombre de dimension, de 2 � 4. Lorsqu'il y a 2 dimensions, on d�finit x et y, et z est par d�faut � 0. Pourquoi aller jusqu'� 4 dimensions alors qu'on fait de la 3D ? C'est � cause des coordonn�es homog�nes. C'est un concept math�matique qui permet d'effectuer toutes les transformations 3D n�cessaires simplement avec des matrices 4x4 et des vecteurs 4D. En pratique, vous n'avez pas � toucher � cette 4e dimension, elle prend normalement toujours la valeur de 1. Si vous voulez en savoir plus, allez faire un tour dans le redbook ou sur des sites de maths.
  • y d�finit le type des param�tres : 'i' pour int, 's' pour short, 'f' pour float, et 'd' pour double.
  • Lorsque l'on rajoute 'v', on passe comme param�tre un pointeur sur les coordonn�es plut�t que les coordonn�es elles-m�me

Vous vous servirez en fait principalement de GL_TRIANGLES et GL_QUADS. Mais l� nous allons nous servir de GL_LINES. En effet, maintenant que vous savez dessiner les primitives (donc que vous savez tout dessiner), nous allons �tudier les transformations de base en OpenGL. Et pour cela, le plus simple est de dessiner un rep�re tridimensionnel. Votre fonction Draw() doit donc �tre :

void Draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glBegin(GL_LINES);
  glVertex2i(0,0);glVertex2i(0,1);
  glVertex2i(0,0);glVertex2i(1,0);
  glVertex2i(0,0);glVertex3i(0,0,1);
glEnd();
SwapBuffers(DC); // glutSwapBuffers(); pour glut
glutPostRedisplay(); // Uniquement pour GLUT
}

Mais si vous lancez le programme tel quel, vous ne verrez rien. Pourquoi ? Parce qu'au d�part, nous sommes plac� en (0,0,0) et nous regardons vers le point (0,0,-1). Or notre objet est situ� en (0,0,0), donc nous ne verrons pas grand chose. Pour changer cela, il suffit d'ins�rer avant glBegin() :

gluLookAt(3,2,3,0,0,0,0,1,0);

gluLookAt() est une fonction tr�s simple et puissante permettant de d�finir un point de vue. Les 3 premiers param�tres d�finissent les coordonn�es du point de vue, les 3 suivant l'endroit o� il regarde, et les 3 derniers un vecteur qui dit o� est le haut de la cam�ra. gluLookAt() effectue les op�rations n�cessaires sur la matrice active afin que le rep�re soit bien orient�. Nous devons donc activer nous-m�me la matrice ModelView gr�ce � glMatrixMode().

Vous pouvez maintenant lancer votre programme, et vous verrez une fen�tre de ce genre (sans les textes, bien s�r) :

Nous allons maintenant utiliser ce rep�re pour �tudier les transformations, au nombre de 3. D�clarez d'abord une variable globale double a=0; et commencons.

Les prinicpes fondamentaux :

  • Lorsque vous avez effectu� une transformation, tous les objets dessin�s apr�s cette transformation sont affect�s, tant que glLoadIdentity() n'est pas appel� (auquel cas les objets ne seront plus transform�s) ;
  • Les modifications affectent directement le rep�re de coordonn�es et se basent sur le rep�re de coordonn�es. Le axes utilis�s sont donc toujours les axes locaux. C'est-�-dire que si vous avez fait une rotation autour de l'axe X, et que vous voulez faire une rotation autour de l'axe Y, cette rotation s'effectuera autour de l'axe modifi� par la premi�re rotation (vous verrez un exemple concret tout-�-l'heure) ;
  • Un objet dessin� ne peut plus �tre modifi�.

L'homot�tie ( glScalef / glScaled ) :
Il s'agit d'un agrandissement ou une r�duction par rapport au centre du rep�re de coordonn�es. Si vous �tes un habitu� de 3DS, cette fonction revient � faire un Non-Uniform Scaling sur tous les objets dessin�s apr�s. Exemple : ins�rez avant le glBegin() de Draw() les lignes suivantes (sans oublier d'inclure math.h pour les fonctions trigo) :

glScaled(1.-cos(a)/3.,1.+cos(a)/3.,1.+cos(a)/3.);
a+=.1;

Et vous verrez une belle animation dans ce genre :

Le rep�re est agrandi ou r�duit selon certains axes. Comme je l'ai dit pr�c�demment, toutes les transformations qui suivent seront bas�es sur le nouveau rep�re, tant que celui-ci n'aura pas �t� r�initialis� par glLoadIdentity(). Donc vous translatez un objet apr�s avoir effectu� une r�duction par glScale(), le d�placement sera plus court, puisque le rep�re aura diminu�.

la translation ( glTranslated / glTranslatef ) :
C'est en fait un d�placement selon le vecteur pass� en param�tre. Le meilleur moyen de l'expliquer est de fournir un exemple. � la place du glScaled, �crivez :

glTranslated(cos(a),0,sin(a));

Et ca donne :

Je ne le r�p�terais jamais assez : les transformations affectent aussi le syst�me de coordonn�es. Donc si vous avez effectu� une translation, et qu'ensuite vous vouliez faire une homot�tie, le centre de cette homot�tie aura lui aussi �t� d�plac�.

la rotation ( glRotated / glRotatef ) :
Elle permet d'effectuer une rotation autour de n'importe quel axe. On lui passe comme param�tre l'angle en degr� et les coordonn�es x,y et z du vecteur de rotation. La rotation fait tout tourner, y compri le rep�re lui-m�me (comme les autres transformations d'ailleurs). Donc si vous faites une premi�re rotation selon un vecteur v1, et que vous voulez faire une deuxi�me rotation selon un autre vecteur v2, n'oubliez pas que v2 a lui aussi subi la premi�re rotation ! Un petit exemple ?

glRotated(a*180/3.14,1,1,1);

donne :

Vous pouvez bien s�r combiner les transformations. Essayez par exemple les 3 en m�me temps, c'est assez sympa.

Et voil� ! Vous savez tout sur le dessin et les transformation et OpenGL. Vous pouvez donc maintenant tout dessiner ! Bon, OK, c'est lourd de dessiner une mobylette � la mano, mais en fait glu vous permet d'y arriver plus facilement : elle fournit des primitives moins primitives, avec gluSphere, gluDisk, gluCylinder, gluPartialDisk... Etudiez ces fonctions avec F1, et amusez-vous � dessiner de petits objets et � tourner autour. Je vous rapelle que le meilleur moyen d'apprendre est encore d'apprendre par soi-m�me. Donc entra�nez-vous � manier les transformations et les primitives jusqu'� ce que vous vous soyez bien familiaris�s avec.

La prochaine fois, nous verrons le coloriage, alors pr�parez vos crayons de couleurs ;-)



Antoche
 


← Initialiser OpenGL avec GLUT↑ Tutoriaux OpenGL ↑Les couleurs →