Les plus extrémistes d’entre vous (n’est-ce pas Daboul ?) décideront de coder tout un programme (gestion des fenêtres, des threads etc.) sur des bases soit-disant saines, en API Win32 par exemple. Je les plains d’avance. Pour les plus réalistes (paresseux ?), il existe 2 librairies qui se chargent de tout ça : GLUT et AUX.
1. GLUT, l’OpenGL Utility Toolkit
OpenGL
ne s’occupant pas des opérations relatives au système ou au fenêtrage, il
laisse la place à d’autres API, dont GLUT fait parti. Il existe des implémentations
de GLUT pour Windows NT, X-Window et OS/2, ce qui permet de compiler le
même code source sur toutes les plates-formes.
GLUT est une interface
entre le programme et l’humanoïde qui se trouve derrière l’écran, la souris,
ou le joystick. Sa programmation est de type événementielle et chaque agitation
de l’humain est considéré comme un événement qui sera géré par des fonctions
personnalisées (callback). Pour l'utiliser, il suffit d’inclure « glut.h »
à votre programme et compiler votre projet avec la librairie « glut32.lib ».
Tous ces fichiers sont fournis en annexe.
1.1. Un exemple
Voici un premier exemple de programme utilisant GLUT :
#include <GL/glut.h> //fonctions GLUT
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (800,600);
glutCreateWindow (argv[0]);
glutDisplayFunc (display);
glutReshapeFunc (reshape);
glutIgnoreKeyRepeat(1);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardup);
glutSpecialFunc(special);
glutSpecialUpFunc(specialup) ;
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutPassiveMotionFunc(motion);
glutIdleFunc (IntelligenceArtificielle);
glutMainLoop ();
return(0);
}1.2. L’initialisation
Initialiser un programme demande, dans l'ordre :
· glutInit(int *argc, char **argv) : A être appelé avant tout autre fonction GLUT.
· glutInitDisplayMode(unsigned int mode) : différencie les mode RGBA et couleur indexé, ainsi que le double-buffering et les buffers à utiliser (depth, stencil, accumulation), que nous étudierons par la suite
· glutInitWindowPostion(int x, int y) : no comment
· glutInitWindowSize(int width, int size) : no comment
· glutCreatWindow(char *string) : crée la fenêtre (et un contexte OpenGL) avec tous les paramètres spécifiés avant.
Elle renvoie un identifiant unique pour la nouvelle fenêtre. Attention : la fenêtre ne sera pas affichée avant l’appel à glutMainLoop().1.3. Les callbacks
Viennent ensuite les « callback ». Il s’agit de spécifier quels sont les fonctions à appeler suivant les événements qui se produisent. On peut changer les fonctions appelées à n’importe quel moment. Si on spécifie la valeur NULL comme adresse de fonction à utiliser, cela a pour effet de désactiver le « callback » correspondant. Elles sont par défaut à NULL. Les plus utilisés sont :
· glutDisplayFunc(void(*func)(void)) : indique la fonction à utiliser lors de l’affichage graphique.
· glutReshapeFunc(void(*func)(int w, int h)) : si la fenêtre est redimentionnée
· glutKeyboardFunc(void(*func)(unsigned char key, int x, int y)) et glutMouseFunc(void(*func)(int button, int state, int x, int y)) : événement clavier et souris.
Il existe d'autres évènements pour la souris, comme par exemple une fonction qui s'active dés que la souris bouge sur l'écran etc ...
1.4. Les Animations
La fonction glutIdleFunc(void (*func)(void)) est lancée lorsque le système n’a plus rien à faire (affichage terminé, pas d’évènements clavier … NULL passé en paramètre désactive cette fonction. Elle sert à faire des animations.
1.5. Les fonctions de dessin 3D évoluées
GLUT peut se charger de dessiner des objets 3D centrés
sur l’origine en mode fil de fer (wire) ou solide (solid). Les objets sont :
cone, icosahedron, teapot (le fameux), cube, octahedron, tetrahedron, dodecahedron,
sphere, tore.
Pour dessiner un cube ou une sphère, on utilise par
exemple les fonctions :
void glutWireCube(Gldouble size) ;
void glutSolidCube(Gldouble size) ;
void glutWireSphere(Gldouble radius, Glint slices, Glint stacks) ;
void glutSolidSphere(Gldouble radius, Glint slices, Glint stacks) ;
1.6. Exécuter le programme
Pour exécuter le programme et voir réellement quelque chose s’afficher après l’initialisation, il faut appeler la fonction : glutMainLoop(void). On rentre alors dans la boucle infinie d’exécution. Ca doit être à peut de choses prêt la dernière ligne du programme. On ne pourra sortir de cette boucle que par un exit().
2. AUX (AUXiliary Librairie), un GLUT pour Windows uniquement
Tout comme GLUT, AUX s’occupe pour vous des opérations relatives au système. Il est lui aussi de type évènementiel et adopte une syntaxe fort proche de celle de GLUT, à tel point que l’on se demande qui à copié sur qui… Il suffit de remplacer GLUT par AUX dans le nom d’une fonction !!! On ne peut pas faire plus simple. Seuls changent les fonctions de gestions des évènements clavier et souris. GLUT n’a que 2 fonctions pour le clavier tandis que AUX a besoin d’une fonction par touche. Pour la souris, GLUT propose plus de fonctions que AUX.
Il suffit, pour utiliser AUX, d’inclure « glaux.h » et surtout « windows.h » dans votre programme et de compiler avec la librairie « glaux.lib » incluse dans votre projet. Là encore, tous ces fichiers sont fournis en annexe.
Exemple d’initialisation de la session OpenGL sous AUX :
#include <windows.h> // obligatoire !!!
#include <gl\gl.h> // fonctions OpenGL
#include <gl\glaux.h> // fonctions AUX Library
void main(void)
{
auxInitDisplayMode(AUX_DOUBLE | AUX_RGBA | AUX_DEPTH | AUX_STENCIL);
auxInitPosition(100,100,LARGEUR,HAUTEUR);
auxInitWindow("Moteur 3D");
auxReshapeFunc(Reshape);
auxKeyFunc(AUX_UP,Key_up); //hé oui, une fonction par touche !
auxKeyFunc(AUX_DOWN,Key_down);
auxKeyFunc(AUX_LEFT,Key_left);
auxKeyFunc(AUX_RIGHT,Key_right);
auxKeyFunc(AUX_a,Key_a);
auxKeyFunc(AUX_z,Key_z);
auxKeyFunc(AUX_q,Key_q);
auxKeyFunc(AUX_s,Key_s);
auxKeyFunc(AUX_g,Key_g);
auxKeyFunc(AUX_h,Key_h);
auxKeyFunc(AUX_f,Key_f);
auxKeyFunc(AUX_j,Key_j);
auxKeyFunc(AUX_k,Key_k);
auxKeyFunc(AUX_2,Key_2);
auxKeyFunc(AUX_8,Key_8);
auxKeyFunc(AUX_4,Key_4);
auxKeyFunc(AUX_6,Key_6);
auxKeyFunc(AUX_9,Key_9);
auxKeyFunc(AUX_3,Key_3);
auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,Mouse_Move); //pour la …souris
auxIdleFunc(Animation); //est lance dés que le système
//n’a rien à faire.
auxMainLoop(Main_part); //Boucle principale
}
3. GLUT vs AUX
D’une manière générale, GLUT est plus complet qu’AUX et il n’est pas confiné à un seul système d’exploitation. « Alors pourquoi utiliser AUX ? » me direz-vous. Mais simplement parce que GLUT, ou plutôt son implémentation pour WINDOWS n’est pas parfaite. J’ai rencontré pas mal de problèmes avec les textures. J’ai bien sûr essayé plusieurs versions de la librairie, mais rien n’y faisait. Alors j’ai opté pour AUX, avec lequel je n’ai plus de problème en ce qui concerne les textures. Car notez tout de même que AUX bugue aussi : on ne peut pas par exemple définr une CallListe avec une fonction de dessin prédéfinie de cette librairie (ex : auxSolidSphere()).
Bref, chacun a ses petits avantages et ses inconvénients. Libre à vous de choisir. De toute façon, ils sont tellement similaires du point de vue syntaxique, que cela ne sera pas difficile de passer de l'un à l'autre. Au passage, notez que tous les exemples, que je donnerai par la suite, seront fait avec AUX.