OpenGL avec GtkGLArea
Par Xavier Michelon


 
   
Les fonctions de rappel

Si vous observez le début de chacune des fonctions de rappel, vous remarquerez qu’elles contiennent toutes un appel a gtk_gl_area_make_current(), qui prend comme paramètre le widget OpenGL. Cet appel nécessaire permet de rendre actif le contexte OpenGL de la fenêtre. N’oubliez pas que vous avez la possibilité de travailler avec plusieurs contextes, d’où l’utilité de cette fonction. gtk_gl_area_make_current() renvoie true si l’activation s’est bien déroulée et FALSE en cas de pépin, ce qui ne devrait pas arriver si votre application est correctement construite.

Les fonctions de rappel liées au widget OpenGL se terminent en général par un appel à gtk_widget_queue_draw(), qui émet un signal expose forçant le widget à se redessiner pour prendre en compte les modifications induites par la fonction de rappel.

Nous avons déjà parlé de la fonction de rappel d’initialisation initGLArea(). Elle est fortement similaire à ce que nous avions avec Glut. La fonction affichage() associée à l’événement ‘expose’ présente deux subtilités :

- Elle commence par un test. Les événements sont stockés dans une pile avant d’être traités par le gestionnaire GTK. Il se peut qu’à un moment donné, plusieurs événements ‘expose’ pour le même widget soit présents dans la pile. Il est inutile de traiter chacun de ces événements. Un seul réaffichage suffit. Sachant que le membre ‘count’ de la structure ‘evenement’ passée en paramètre par le gestionnaire GTK contient le nombre d’événements de type ‘expose’  restant dans la pile, on ne redessine le widget que si count=0.

- Elle se termine par gtk_gl_swap_buffers() qui, comme vous l’aurez deviné, échange les deux tampons d’image utilisés puisque nous avons activé le double buffering en créant notre fenêtre.

La gestion de la souris est prise en charge par la fonction de rappel mouvementSouris. Lors de l’appel, c’est-à-dire en cas de mouvement de la souris au-dessus du widget OpenGL, la fonction reçoit une structure événement contenant des informations sur l’état de la souris au moment de l’événement. Je vous invite à vous référer au livre de David Odin si vous ne vous rappelez plus les subtilités du motion hint.

La portion de code ci-dessous permet d’extraire de la structure ‘evenement’ les données de position de la souris (x,y) et d’état des boutons (etat). Le mécanisme de zoom et de rotation est identique à celui que nous utilisions avec Glut.

J’attire votre attention sur un dernier point. Pour calculer les rotations et le zoom de notre objet, nous utilisons les variables xprec et yprec qui servent à stocker les précédentes positions de la souris afin de pouvoir calculer le déplacement de la souris relativement à sa dernière position. Il faut nous assurer que ces variables sont correctement initialisées sous peine de voir notre cube subir une rotation ou un zoom aléatoire lors du premier clic dans la fenêtre. Pour cela, on connecte à la fonction rappelMap() le signal ‘map_event’ qui est émis lorsque la fenêtre est affichée à l’écran.