Introduction
Cet article continue notre s�rie sur GLUT (GL Utility Toolkit), la librairie-boite � outils- pour OpenGL �crite par Mark Kilgard. Comme nous l'avons dit dans notre pr�c�dent article (Fen�tres et Animations) GLUT est une librairie tr�s int�ressante et tr�s utile pour tous les d�veloppeurs OpenGL car elle permet d'�crire du code portable. GLUT cache au d�veloppeur tous les d�tails emb�tant du gestionnaire de fen�tres et de l'interface graphique .
GLUT est divis� en plusieurs ensembles de fonctions. Dans cet article nous d�taillerons l'ensemble de gestion de fen�tres (et de sous-fen�tres). Comme son nom l'indique, elle prend en charge les t�ches li�es aux fen�tres utilis�es par votre application OpenGL�: cr�er, d�truire, iconifier une fen�tre�; mise en avant/arri�re plan, cacher, d�placer�; fixer les titres, la position, etc...
Le sous-ensemble de Gestion de Fen�tre ( Windows Management Sub-Api)
Voici une liste exhaustive des fonctions support�es par la gestion de fen�tre de GLUT (pour ce qui est de la version 3.6)�:
int glutCreateWindow(char *name) |
Cr�e une nouvelle fen�tre principale |
int glutCreateSubWindow(int win,
int x, int y, int width, int height) |
Cr�e une sous-fen�tre |
void glutSetWindow(int winId) |
Fait de la fen�tre ayant l'identificacteur winId la fen�tre courante |
int glutGetWindow(void) |
Demande l'identificateur de la fen�tre courante |
void glutDestroyWindow(int winId) |
D�truit la fen�tre identifi�e par winID |
void glutPostRedisplay(void) |
Informe le gestionnaire d'�v�nements de GLUT que la fen�tre courante doit �tre r�affich�e |
void glutSwapBuffers(void) |
Effectue le changement de buffer. |
void glutPositionWindow(int x, int y) |
Demande le changement de position de la fen�tre |
void glutReshapeWindow(int width, int height) |
Demande le changement de dimension de la fen�tre |
void glutFullScreen() |
Demande la mise en pleine �cran |
void glutPopWindow(void)
void glutPushWindow(void) |
met � l'avant plan ou � l'arri�re plan la fen�tre active |
void glutShowWindow(void)
void glutHideWindow(void)
void glutIconifyWindow(void) |
Montre, cache, iconifie la fen�tre courante |
void glutSetWindowTitle(char *name)
void glutSetIconTitle(char *name) |
Fixe le titre de la fen�tre |
Utilisation des sous-fen�tres
L'utilisation de la plupart des fonctions ci-dessus est tr�s simple. Certaines furent d�taill�es dans notre pr�c�dent article�: glutPosRedisaply, glutCreateWindow, glutPositionWindow, glutSwapBuffers,... etc. Les nouvelles sont tr�s simples � utiliser et la description pr�c�dente dit l'essentiel de ce qu'elles font, par exemple�: glutSetIconTitle, glutFullScreen,... etc. Cependant l'utilisation n'en n'est pas si simple, c'est pourquoi nous avons d�cid� de vous donner un exemple simple et de commenter les d�tails de son impl�mentation.
Voici le code source d'une petite d�mo OpenGL-GLUT (../../common/March1998/example1.c, ../../common/March1998/Makefile). Son but est de vous montrer�: (a) comment g�rer les sous-fen�tres, (b) comment utiliser le clavier pour interagir avec votre application OpenGL,(c) comment afficher du texte dans une fen�tre OpenGL.
(s'il vous pla�t, imprimez ou ayez le code source de ../../common/March1998/example1.c sous la main pendant que nous poursuivons l'explication.)
D'abord regardons la fonction main(). Cette application commence comme toutes les applications GLUT par la phase d'initialisation�: parcours des arguments de la ligne de commande, choix du mode d'affichage, enfin placement et dimensionnement de la fen�tre initiale. Comme notre application va manipuler plus d'une fen�tre il est n�cessaire de stocker l'entier d'identification de fen�tre retourn� par la fonction glutCreateWindow. La variable winIdMain est une r�f�rence � cette fen�tre. Il nous faut maintenant fixer les fonctions appel�es en r�ponse � des �v�nements associ�s � la fen�tre winIdMain (appel�es fonctions callback)�; Plusieurs fonctions callback sont d�finies et agissent toutes sur la fen�tre principale�: une fonction pour l'affichage (mainDisplay) qui dessine la sc�ne, une fonction de retaillage (mainReshape) qui g�re toute transformation du cadre de la fen�tre principale - par exemple un redimensionnement, keyboard qui g�re les actions venant du clavier, et idle qui est appel� quant il n'y a aucun autre �v�nement � traiter et dont on se sert pour la gestion des animations (cf. Fen�tres et animations pour une description plus d�taill�e du r�le de idle)�;
La premi�re chose importante � savoir est que dans GLUT, il ne peut y avoir qu'une seule fonction callback idle. La fonction idle est globale et commune � toutes les fen�tres de l'application. Aussi prenez cela en compte lorsque vous concevez votre fonction idle, elle doit effectuer le rafra�chissement de toutes les fen�tres et sous-fen�tres de votre application.
Ensuite dans le code viens la cr�ation de la sous-fen�tre (winIDSub). Pour cr�er une sous-fen�tre, vous devez fournir l'ID de la fen�tre de plus haut niveau , ici winIDMain, les coordonn�es x et y de la sous-fen�tre par rapport � la fen�tre parente, et la hauteur et la largeur d�sir�e pour cette sous-fen�tre. Apr�s la cr�ation de la sous-fen�tre GLUT retourne une r�f�rence sur cette fen�tre � notre programme, nous pouvons maintenant fixer les fonctions callback de winIDSub. Dans notre exemple nous d�finissons deux fonctions callback�: une pour l'affichage (subDisplay) et une pour les modifications sur le cadre (subReshape).
Quand GLUT ouvre une sous-fen�tre il lui fournit un environnement OpenGL complet. Il y a donc une baisse des performances induite par l'utilisation de sous-fen�tres car le driver de la carte vid�o doit rafra�chir la zone m�moire pour chaque fen�tre en plusieurs passes. Gr�ce � des environnements OpenGL ind�pendant, chaque fen�tre peut avoir son propre syst�me de coordonn�es par exemple. Dans ../../common/March1998/example1.c le syst�me de coordonn�es est d�fini dans mainDisplay() et subDisplay() respectivement. Regardez ces deux fonctions, elles sont assez simples et si vous avez suivis notre article de janvier sur OpenGL ("�rendu de polygones "�) vous n'aurez pas de mal � les comprendre.
La fonction mainDisaplay() dessine un triangle avec des ar�tes�Rouges, Bleues et Vertes. OpenGL calcul par interpolation la couleur de chaque point de la surface. Avant de dessiner le triangle nous avons ajout� un ordre glRotate, qui fait tourner le triangle autour de l'axe Z (perpendiculaire � l'�cran), l'angle de rotation (spin) est incr�ment� doucement dans la fonction idle pour donner l'illusion de rotation.
La fonction d'affichage associ�e � winIDSub est elle aussi tr�s simple. Tout d'abord elle remplit le fond en gris, ensuite elle dessine un contour vert sur le cadre de la sous-fen�tre, enfin elle inscrit du texte. Plus tard nous expliqueront comment se fait le dessin de texte sous GLUT. Pour le moment notez juste que glRastePos2f(x,y) fixe la position � laquelle le texte sera affich� et que les coordonn�es x,y sont donn�es relativement au syst�me de coordonn�es de la sous-fen�tre (d�fini dans subReshape() ).
La sous-fen�tre agit comme une zone de texte pour les donn�es venant de l'animation. Cette une application un peu b�te, nous aurions pu afficher la zone de texte sur la fen�tre principale et obtenir le m�me r�sultat (en plus performant). Dans certaines circonstances cependant il est pr�f�rable d'ouvrir une sous-fen�tre pour la zone de texte. Par exemple lorsque l'animation est en 3D avec des jeux de lumi�res et des effets atmosph�riques, et que vous ne voulez pas voir votre zone de texte d�form�e par la perspective, l'�clairage, les ombres, le brouillard etc. Dans ce cas une sous-fen�tre est un bon choix car compl�tement isol� de l'animation 3D.
Il y a une diff�rence cruciale entre une fonction de retaillage pour une fen�tre principale et pour une sous-fen�tre. Quand un �v�nement de retaillage est intercept�, seul la fonction callback de retaillage de la fen�tre principale est appel�e, dans notre exemple mainReshape(). Nous devons appeler les fonctions subReshape() dans le code de la fonction mainReshape(). Cela est normal car la taille et la position des sous-fen�tres ne sont connues que relativement � celles de la fen�tre principale. C'est pourquoi si vous regardez maintenant le code de notre fonction mainReshape() vous verrez que tout d'abord nous fixons la matrice de projection pour la fen�tre principale, et qu'ensuite nous basculons sur la fen�tre winIDSub et appelons la fonction subReshape() avec les param�tres de largeur et de hauteur d�duits de ceux de winIDMain.
Il a �t� mentionn� plus haut que la fonction callback idle() devait mettre � jour la fen�tre principale et toutes les sous-fen�tres d�'une application OpenGL. Dans notre exemple idle() met d'abord � jour les variables de l'animation (time et spin) et ensuite demande � la fen�tre principale et � la sous-fen�tre de se redessiner.
Le Clavier
J'ai ajout� deux touches actives au programme. En appuyant sur la touche ��i�� vous pouvez activer ou d�sactiver la zone d'information et avec la touche ��q�� vous quittez l'application�; Essayez-les�:)
A chaque fois que vous tapez sur une touche du clavier, GLUT g�n�re un �v�nement clavier. Ces �v�nements sont g�r�s par des fonctions callback. En principe chaque fen�tre � ses propres fonctions callback. Quand la souris est � la position (x,y) dans une fen�tre (ou sous-fen�tre) et qu'un �v�nement clavier est lanc�, c'est la fonction callback associ�e � cette fen�tre qui est appel�e. Cette fonction prend comme argument le code ASCII (cod� sur un unsigned char) associ� � cette touche, ainsi que les coordonn�es x et y du curseur � ce moment. Dans ../../common/March1998/example2.c il n'y a pas d'utilisation de x et y, mais je suis s�r que vous pouvez imaginer des applications tirant partie de cette possibilit�.
Dans notre exemple, seule la fen�tre de plus haut niveau poss�de une fonction callback. Si vous essayez de presser les touches ��i�� et ��q�� alors que le curseur est sur la sous-fen�tre, vous remarquerez que rien ne se passe. Par d�faut lorsqu'aucune fonction callback n'a �t� d�finie toutes les touches sont ignor�es. Gardez cela en t�te si plus tard vous utilisez plusieurs fen�tres et d�sirez avoir une bonne gestion du clavier.
J'ajouterai enfin, que l'appel aux fonctions callback de traitement des �v�nements claviers peuvent �tre d�sactiv� en passant NULL � la fonction glutKeyBoardFunc().
Afficher du Texte
Afficher du texte sous OpenGL et GLUT est une vraie merde�!. D�sol� de dire cela, mais c'est vrai. Je ne sais pas exactement pourquoi les fonctions de gestion du texte ont �t� autant n�glig�es dans la librairie OpenGL. La vieille librairie GL de Silicon Graphics avait quelques fonctions de haut niveau pour traiter le texte en mode graphique et il y avait une librairie auxiliaire pour changer de fonte. OpenGL ne propose que quelques primitives pour afficher des images 2D, ce qui veut dire que vous devez cr�er votre propre librairie � base d'image 2D pour chaque caract�re, tenir compte du redimensionnement des espaces...vous voyez ce que je veux dire.
GLUT r�sout partiellement le probl�me du texte sous OpenGL. Il propose une fonction glutBitmapCharacter qui affiche un seul caract�re � l'�cran � la position sp�cifi� par glRastePos. J'ai ajout� un couple de fonctions, drawString() et drawStringBig() qui vous rendrons la vie un peu plus facile pour afficher des cha�nes.
Conclusion
Ceci conclut notre introduction simple � l'utilisation des sous-fen�tres avec GLUT. Je dois ajouter qu'il est bon de les exp�rimenter et de les tester sous plusieurs environnements, car malheureusement les sous-fen�tres de GLUT ne sont pas compl�tement op�rationnelles sous tous les environnements. Les utilisateurs de cartes 3Dfx s'apercevrons que les sous-fen�tres ne sont pas op�rationnelles � cause de limitations mat�rielles. J'ai �galement rencontr� de forte baisse de performance lors de l'utilisation de sous-fen�tres sur certaines plates-formes. Par exemple sur mon Linux pour Alpha avec une matrox millenium de 2Mo l'utilisation de sous-fen�tres diminue par deux les performances, probablement parce que le serveur X pour Alpha ne supporte aucune acc�l�ration mat�rielle. D'un autre cot�, la m�me application sous windows 95, avec une ATI RageII 2Mo et les drivers OpenGL de SGI tourne parfaitement.
Comme les d�veloppements sous Linux avancent tr�s vite, il est possible que dans un futur proche la plupart
de ces probl�mes de performances et d'incompatibilit�s n'existeront plus. Pour l'instant gardez � l'esprit que cela existe et qu'il vaut
mieux utiliser les sous-fen�tres avec pr�caution.
Bien s�r les utilisateurs exp�riment�s pourrons toujours contourner l'utilisation de sous-fen�tres en jouant
avec la pile des matrices, mais comme nous n'avons pas �tudi� cela encore, vous m'excuserez de le garder pour plus tard...�;) )
|