OpenGL, Créer une fenêtre
Sommaire |
[modifier] Objectif
Pour commencer, nous voulons créer un programme qui crée une simple fenêtre, qui servira de base à nos prochains tutoriels. Ici, nous n'utiliserons ni MFC (Microsoft Foundation Class), ni les fonctions de fenêtrage de Windows, mais uniquement GLUT, librairie annexe à OpenGL fournissant un système complet de gestion du fenêtrage.
Notre objectif est donc la création d'une fenêtre simple, de fond noir, avec une taille déterminée. Le programme que nous allons créer représentera en fait le squelette de toute application OpenGL.
[modifier] Les bases de la programmation OpenGL
Avant de se lancer dans notre premier programme utilisant OpenGL, rappelons quelques-uns des grands principes de l'utilisation de l'API qui nous serviront ici.
D'abord considérons les types de données utilisés par OpenGL. On retrouve les mêmes types que la programmation classique en C "à la sauce OpenGL" : les entiers (int) deviennent GLint, les doubles (double) deviennent GLdouble... D'une manière générale, les types de données sous OpenGL sont de la forme "GLxxx".
Pour les fonction, leur nom est dépendant du nombre et du type de leurs paramètres : le nom d'une fonction est constitué d'abord du préfixe"gl", puis de son nom de base, suivi du nombre de paramètres d'entrées, et enfin de leur type. Par exemple, la fonction servant à définir un vecteur en 3 dimensions, de composantes entières s'appelle glVertex3i ( int x, int y, int z). La fonction qui définit un vecteur en 2 dimensions, de composantes flottantes se nomme glVertex2f (... ).
On peut également évoquer les constantes, dont le nom est toujours de la forme "GL_xxx".
Rajoutons, puisque nous utiliserons GLUT, que les fonctions fournies par OpenGL commencent par "gl", tandis que les fonctions fournies par GLUT commencent par "glut".
Enfin, nous pouvons parler d'un des aspects essentiels d'OpenGL : la machine d'état. En effet, OpenGL est basée sur des variables d'état, (la couleur utilisée, le mode de projection utilisé par exemple...). L'utilisation de ces variables passe par l'utilisation des fonctions glEnable et glDisable, servant à activer / désactiver les variables de mode.
[modifier] Mise en oeuvre
[modifier] Fichiers à inclure
Nous utiliserons les fonctions d'OpenGL, et celles de GLUT. L'inclusion des fichiers d'en-tête sera donc :
#ifdef WIN32 //Pour la portabilité du code.
#include <windows.h>
#endif
#include <gl/gl.h>
#include <gl/glut.h>
[modifier] Déclaration des fonctions
En plus de la fonction principale main() autour de laquelle tout sera articulé, nous définissons une fonction de dessin de la scène :
void Display();
[modifier] Procédure principale "main"
Notre fonction principale doit récupérer les paramètres passés en ligne de commande, pour les retransmettre au GLUT. On procède d'abord à la création de la fenêtre, puis on définit les 3 fonctions déclarées plus haut.
int main(int argc, char** argv)
{
La première étape consiste à initialiser le GLUT avec glutInit(int **argcp, char **argv). arg et argv étant respectivement le nombre et la liste des paramètres passées en ligne de commande, on les transmet à glutInit :
glutInit(& argc, argv);
On initialise ensuite le mode de rendu grâce à la fonction glutInitDisplayMode(unsigned int mode). L'argument mode est un paramètre, ou une combinaison de paramètres (param1 | param2...) déterminant le mode d'affichage utilisé. Voici la liste des paramètres pouvant être utilisés :
GLUT_RGBA mode "vraies couleurs" 32 bits. (mode par défaut)
GLUT_RGB idem
GLUT_INDEX mode couleurs indéxées
GLUT_SINGLE "simple buffering"- un seul tampon (mode par défaut)
GLUT_DOUBLE "douflle buffering"- deux tampons
GLUT_ACCUM tampon à accumulation
GLUT_ALPHA composante alpha sur les tampons de couleur
GLUT_DEPTH tampon de profondeur
GLUT_STENCIL tampon pochoir
GLUT_MULTISAMPLE échantillonnage multiple
GLUT_STEREO mode stéréo
GLUT_LUMINANCE modèle de couleur luminance
L'objectif de ce tutoriel étant de créer une simple fenêtre à fond noir, nous n'utiliserons que les paramètres par défaut : un seul buffer, couleurs vraies. La ligne suivante pourrait donc être supprimée sans problème, cela n'affecterait en rien le bon fonctionnement du programme. J'ai choisi de vous la montrer ici puique cela fait partie des bases de l'utilisation d'OpenGL avec GLUT.
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
Il est important de préciser ici la notion de buffer, ou "tampon", qui désigne d'une manière globale une zone de la mémoire contenant des données. Ici, le seul buffer utilisé est le buffer d'affichage : le frame buffer. Les autres buffers utilisés par OpenGL, tels que le Depth Buffer (tampon de profondeur), ne nous intéresse pas pour le moment.
Ensuite, il nous faut définir la taille et la position de la fenêtre : GLUT met pour cela 2 fonctions à notre disposition : glutInitWindowSize(int width, int height) et glutInitWindowPos(int x, int y) :
glutInitWindowSize(640, 480); glutInitWindowPosition(50, 50);
Notons que si on veut passer en mode plein écran, on utilisera glutFullScreen()au lieu de glutInitWindowSize().
Pour en finir avec la fenêtre proprement dite, il nous reste à la créer avec la fonction glutCreateWindow(const char *title). title est le titre qui sera donné à la fenêtre. Notons que la fonction retourne une variable entière qui peut être utilisée par la suite pour identifier la fenêtre.
glutCreateWindow("Fenetre OpenGL");
Enfin, on termine notre procédure principale en définissant le squelette principal du programme, à savoir la définition de la (ou des) fonction(s) de traitement des évènements (ou callbacks). Un événement peut être un clic sur la souris, le déplacement de la fenêtre, la fermeture de la fenêtre, etc... Par défaut, l'écoute de ces évènements est désactivée. Pour activer un callback, il suffit d'utiliser la fonction glutxxxFunc, où "xxx" correspond au nom de l'événement : par exemple glutMouseFunc pour la gestion de la souris, glutKeyboardFunc pour le clavier, etc.
Dans notre cas, nous nous intéressons uniquement à l'affichage de la fenêtre, qui sera géré par notre fonction Display() :
glutDisplayFunc(Display);
Après l'activation des callbacks, il ne reste plus qu'à lancer le gestionnaire GLUT, qui se chargera de diriger chaque événement vers la fonction qui correspond.
glutMainLoop(); return 0; }
[modifier] Fonction d'affichage de la scène
La dernière étape consiste ici à utiliser notre fonction Display() qui gère l'affichage de la scène. Vu que le but est de remplir la fenêtre avec la couleur noire, son contenu se limite à :
glClear(GL_COLOR_BUFFER_BIT); glFlush();
La fonction glClear() sert à remplir un buffer avec une valeur, qui est 0 par défaut. GL_COLOR_BUFFER_BITindique que l'on travaille sur le frame buffer. Notons que si on voulait une autre couleur de fond, il faudrait auparavant la définir avec la fonction glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha).
Enfin, la fonction glFlush() termine notre dessin de la scène, en forçant toutes les commandes à être éxécutées, et envoie ainsi le flux de données vers le buffer d'affichage. Si on n'utilise pas glFlush(), alors l'affichage de la scène ne se produit jamais.
Ce document a été publié sur la version 3 du G.C.N. par Le Gritche.
- Auteur Original : Le Gritche
- Date de publication : 29 Juillet 2003


