Vous êtes sur la page 1sur 41

Université Mohammed V

École Mohammadia d’Ingénieurs

GUIDE DE
À LA PROGRAMMATION GRAPHIQUE EN

Prof. Mohamed AGOUZOUL


Département Génie Mécanique
Équipe : Modélisation et Calcul Scientifique en Conception Mécanique

1ère Version janvier 2004


Révision 2008
Révision 2012
infographie avec opengl 2
TABLE DES MATIÈRES

1. PRÉAMBULE ....................................................................................................................................................................... 4
1.1. RÉFÉRENCES ....................................................................................................................................................................... 4
1.1.1. Livres et Manuels .................................................................................................................................................... 4
1.1.2. Sites Web ................................................................................................................................................................ 4
2. LES BIBLIOTHÈQUES............................................................................................................................................................ 4
2.1. GRAPHIC LIBRARY (GL)......................................................................................................................................................... 5
2.2. OPENGL (GL) .................................................................................................................................................................... 5
2.3. OPENGL UTILITY LIBRARY (GLU) ............................................................................................................................................ 5
2.4. OPENGL UTILITY TOOLKIT (GLUT)........................................................................................................................................... 5
2.5. DIVERS .............................................................................................................................................................................. 6
2.6. ORGANISATION DES BIBLIOTHÈQUES (GL, GLU, GLUT) .................................................................................................................. 6
2.6.1. Moteur géométrique (geometric engine) ............................................................................................................... 6
2.6.2. Moteur de numérisation (raster engine) ................................................................................................................ 7
2.6.3. Gestionnaire de numérisation (raster manager) .................................................................................................... 7
2.7. FONCTIONS ET CONSTANTES .................................................................................................................................................. 7
2.7.1. Syntaxe des fonctions et des constantes ................................................................................................................ 7
2.7.2. Fonctions de création (ou Primitives graphiques) .................................................................................................. 7
2.7.3. Fonctions entre begin et end .................................................................................................................................. 9
2.7.4. Autres primitives ................................................................................................................................................... 10
3. CRÉATION ET MANIPULATION DES SCÈNES ...................................................................................................................... 11
3.1. CRÉATION DE LA VUE À VISUALISER........................................................................................................................................ 11
3.2. PRÉSENTATION DES MATRICES D’OPENGL............................................................................................................................... 13
3.3. TRANSFORMATIONS ........................................................................................................................................................... 14
3.3.1. Principes ............................................................................................................................................................... 14
3.3.2. Positionnement des objets (transformations élémentaires)................................................................................. 14
3.4. PILE DES MATRICES ............................................................................................................................................................ 15
3.5. MATRICE « GL_MODELVIEW » (SPÉCIFICATION DU POINT DE VISION) ................................................................................ 15
3.5.1. Positionnement de la caméra ............................................................................................................................... 15
3.5.2. Positionnement de la scène et ses objets ............................................................................................................. 16
3.6. MATRICE « GL_PROJECTION » (PROJECTION ET FENÊTRAGE) .......................................................................................... 16
3.6.1. Projections prédéfinies ......................................................................................................................................... 16
3.6.2. Exemple d’utilisation ............................................................................................................................................ 18
3.7. GESTION DES ENTRÉES (GLUT) .............................................................................................................................................. 18
3.7.1. Le clavier ............................................................................................................................................................... 18
3.7.2. La souris ................................................................................................................................................................ 19
3.7.3. Liste des boutons pour les trois fonctions ............................................................................................................. 19
3.7.4. divers .................................................................................................................................................................... 19
3.7.5. Exemple ................................................................................................................................................................ 19
4. ORGANISATION D’UN PROGRAMME GRAPHIQUE ............................................................................................................ 20
4.1. ÉTAPES DE PROGRAMMATION .............................................................................................................................................. 20
4.2. INITIALISATION .................................................................................................................................................................. 20
4.2.1. Initialisation des états de glut .............................................................................................................................. 20
4.2.2. Initialisation des Paramètres du dessin (ou des variables d’états) ....................................................................... 21
4.3. DÉFINITION DE LA MATRICE « GL_MODELVIEW »........................................................................................................... 23
4.4. DÉFINITION DE LA MATRICE « GL_PROJECTION » ......................................................................................................... 23
4.5. DÉFINITION DES OBJETS À DESSINER ...................................................................................................................................... 23
4.6. GESTION DES ÉVÉNEMENTS (LES CALL-BACKS)......................................................................................................................... 23
4.7. LES BUFFERS (OU PLANS MÉMOIRE) ...................................................................................................................................... 23
4.7.1. Les buffers............................................................................................................................................................. 23
4.7.2. Utilisation ............................................................................................................................................................. 24
4.7.3. Effacement des buffers ......................................................................................................................................... 24
4.8. PROGRAMMES D’ILLUSTRATION............................................................................................................................................ 24
4.8.1. Squelette d’un programme................................................................................................................................... 24
4.8.2. programme 1 : initialisation, polygone et interpolation des couleurs ................................................................. 25
4.8.3. programme 2 : cube, projections et rotations ...................................................................................................... 25
4.8.4. programme 3 : touches spéciales : rotations par flèches .................................................................................... 26
infographie avec opengl 3
4.8.5. programme 4 : lumières et animation .................................................................................................................. 27
4.9. GESTION D'UN PROCESSUS EN TÂCHE DE FOND ........................................................................................................................ 28
4.9.1. Utilisation de la fonction ...................................................................................................................................... 28
4.9.2. Programme 5 : animation en tâche de fond ....................................................................................................... 28
4.10. LES LISTES D'AFFICHAGE .................................................................................................................................................. 29
4.10.1. Définition .............................................................................................................................................................. 29
4.10.2. Syntaxe des commandes ...................................................................................................................................... 29
4.10.3. Exemple ................................................................................................................................................................ 30
4.11. LE BROUILLARD ............................................................................................................................................................. 31
4.11.1. Mise en œuvre ...................................................................................................................................................... 31
4.11.2. Exemple ................................................................................................................................................................ 31
4.12. PROGRAMME D’ILLUSTRATION DE L’ILLUMINATION .............................................................................................................. 33
5. ÉLIMINATION DES PARTIES CACHÉES ................................................................................................................................ 34
5.1. ALGORITHME DE LA NORMALE (CULLING)................................................................................................................................ 34
5.1.1. Principe ................................................................................................................................................................. 34
5.1.2. Mise en œuvre par Opengl ................................................................................................................................... 34
5.1.3. Remarques ............................................................................................................................................................ 34
5.2. ALGORITHME DU Z-BUFFER (DEPTH-BUFFER) ....................................................................................................................... 34
5.2.1. Principe et Implantation ....................................................................................................................................... 34
5.2.2. Avantages ............................................................................................................................................................. 35
5.2.3. Inconvénients........................................................................................................................................................ 35
5.2.4. Mise en œuvre par Opengl ................................................................................................................................... 35
5.3. EXEMPLES DE PROGRAMMATION .......................................................................................................................................... 35
5.3.1. programme 6: z_buffer ........................................................................................................................................ 35
6. ANNEXES .......................................................................................................................................................................... 37
6.1. TYPES PRÉDÉFINIS .............................................................................................................................................................. 37
6.2. MASQUES DU MODE D’AFFICHAGE........................................................................................................................................ 37
6.3. LISTE DES FONCTIONS OPENGL, GLU ET GLUT ........................................................................................................................... 37
6.3.1. Bibliothèque gl ...................................................................................................................................................... 37
6.3.2. Bibliothèque glu .................................................................................................................................................... 38
6.3.3. Bibliothèque glut .................................................................................................................................................. 39
6.4. DIVERS ............................................................................................................................................................................ 40
6.4.1. versions et informations ....................................................................................................................................... 40
6.4.2. prochaine versions du document ........................................................................................................................ 40
infographie avec opengl 4

1. PRÉAMBULE
Ces notes de cours sont conçues dans le but d’aider les lecteurs à apprendre, dans des
délais raisonnables, la programmation d’applications graphiques en Opengl. Lors de la
réalisation de ce document nous avons consulté une série de références et de pages web
officielles ou écrites par des développeurs et utilisateurs de ladite bibliothèque.
Le nombre de documents, sous forme de manuels officiels, Livres ou de pages web, est très
important. Une liste non exhaustive de ces références est présentée à la section suivante.
Des sujets, plus spécialisés, seront traités dans le cadre d’autres cours. Ainsi, la
modélisation géométrique et l’élimination des parties cachées seront introduites au cours
d’infographie et détaillée au cours CAO. D’autres sujets feront l’objet d’autres cours : les
maillages, la triangulation, …, etc.
Le choix d’Opengl n’est pas fortuit. La bibliothèque est un standard de fait pour les
développeurs d'applications CAO et des jeux. La bibliothèque est conçue pour permettre la
création des scènes 3D en offrant des possibilités d’animation, de modifications, de rendu
réaliste, ..., etc. Des applications, de renommées, conçues autour d’Opengl, sont
nombreuses et diversifiées.
Plusieurs logiciels de différents domaines sont développés sous OpenGL:
• Modélisation géométrique et CAO : Catia, SolidWorks, Pro-Engineer, ...
• Création et animation 3D : Maya, 3DSMax, Softimage, Blender…
• Jeux Vidéos (micro-ordinateur, console) : Quake, Unreal 2, Half-life, Doom 3 …
OpenGl est aussi de plus en plus compatible avec le matériel (cartes graphiques,
imprimantes, …). Parmi les cartes citons : la Geforce4 de Nvidia, la Radeon 8500 d'ATI, …

1.1. RÉFÉRENCES
1.1.1. Livres et Manuels
• Une liste assez étouffée, de références, est consultable sur le site officiel : http://www.opengl.org
• OpenGL, programming guide the official guide to learning OpenGL Jackie Neider - Tom Davis -
Mason Woo OpenGL architecture review board Addison Wesley ISBN 0-201-63274-8
• OpenGL, reference manual the official reference document OpenGL architecture review board
Addison Wesley ISBN 0-201-63276-4

1.1.2. Sites Web


Plusieurs sites, traitant de la programmation en opengl et ses bibliothèques
complémentaires, sont disponibles sur la toile. Nous mentionnons ci-dessous une liste, non
exhaustive, des sites les plus fréquemment cités
• http://www.opengl.org: site officiel d’Opengl
• http://freeglut.sourceforge.net/
• http://trant.sgi.com/opengl
• http://reality.sgi.com/mjk/
• http://reality.sgi.com/opengl

2. LES BIBLIOTHÈQUES
La bibliothèque de base est complétée par d’autres bibliothèques complémentaires. Dans
cette section, nous donnons les caractéristiques et les fonctionnalités de bibliothèques.
Seules les bibliothèques utilisables sans licence, parmi les plus utilisées, seront présentées.
infographie avec opengl 5
2.1. GRAPHIC LIBRARY (GL)
• Bibliothèque ou interface propriétaire (IRIS GL) développée par Silicon Graphics Inc
(SGI). Son utilisation est soumise à la licence de SGI
• Ancêtre d’Opengl, la bibliothèque GL avait ses propres commandes de fenêtres et de
pilotes de périphériques qui étaient spécifiques à IRIX (OS UNIX de SGI)
• Elle dépend ainsi du système de fenêtrage et par conséquent du matériel.

2.2. OPENGL (GL)


• Bibliothèque standard et sous-ensemble de GL
• Libre d’utilisation : elle ne nécessite pas la licence de SGI
• Début du développement en 1992. Dernière version 3.01
• OpenGL est une API (Application Pprogram Interface) pour les programmes
graphiques. On peut la considérer comme une interface logicielle qui tente de
standardiser les applications
• Elle ne gère pas l’affichage. Elle ne contient pas de fonctions de construction
d'interface utilisateur. Ainsi, elle ne dépend pas du système de fenêtrage et par
conséquent du système d’exploitation (OS) et du matériel. En effet, pour chaque OS,
il faut faire appel à d’autres bibliothèques pour gérer le fenêtrage et les interfaces
(fenêtres, souris, clavier, ...).
• Portabilité : les programmes, basés sur cette bibliothèque, sont indépendants de la
machine hôte et de son système d’exploitation
• Environ 120 fonctions (création, animation et rendu réaliste) d’objets 3D
• C’est une bibliothèque 3D qui calcule les états : position de l’observateur, projections,
fenêtrage (clipping), élimination des parties cachées, interpolation des couleurs, …
• Elle est apte à générer une image bitmap à partir des caractéristiques vectorielles
d'objets
• Les fonctions de la bibliothèque s’appuient sur le hardware : carte vidéo et/ou
accélératrice. À priori, toutes les opérations de base sont accessibles sur la plupart
des cartes graphiques actuelles. Si ces fonctions ne sont pas implémentées au niveau
matériel, la partie logicielle s’occupera de la tâche de la fonction mais l’exécution
devient, relativement, plus lente.
• Le développement de la bibliothèque est contrôlé par le consortium opengl ARB
« OpenGL Architectural Review Board » constitué de plusieurs sociétés et organismes.
Parmi lesquels, figurent les principaux acteurs de l’informatique : SGI, SUN,
HP/compaq, Microsoft, Cray Research, DEC, Evans et Sutherland, …

2.3. OPENGL UTILITY LIBRARY (GLU)


• La bibliothèque est libre d’utilisation et elle est distribuée gratuitement
• les fonctions de la bibliothèque sont écrites en OpenGL
• Elle offre des fonctions de création ou de manipulation : Redimensionnement de
l’image lors du changement des dimensions de la fenêtre d’affichage, constructions
d'objets complexes, projection perspective, triangulation de polygones, …
• Création de quelques objets de base : Sphère, cylindre, …
• Création de courbes et surfaces basées sur les NURBS (Non-Uniform Rational B-Spline)
• Description des erreurs (voir gluErrorString())

2.4. OPENGL UTILITY TOOLKIT (GLUT)


• C’est une bibliothèque complémentaire, développée par Mark J. et Kilgard de SGI, qui
s’occupe de la gestion du système de fenêtrage. Elle s’occupe de l’affichage, la

1
Annoncée le 11 août 2008 http://www.opengl.org/
infographie avec opengl 6
gestion de l’environnement multi-fenêtrage, la gestion des menus pop-up, la gestion
des périphériques d'entrée (souris, clavier, joystick, …), …
• Ses développeurs (cf. site officiel Opengl) l’ont conçue pour que le code source soit
portable à toutes (ou presque) les plates-formes dont les systèmes d’exploitation sont
à base du système X-Window (Mac, Ms Windows, …). GLUT est indépendante du
système de fenêtrage.
• Elle a été implémentée sur d’autres systèmes de fenêtrage autre que le système X-
Window tel que OS/2 et Mac OS. Cependant, ces versions ne font pas partie de la
distribution officielle
• GLUT remplace l’ancienne bibliothèque GLAUX (cf. divers ci-dessous)
• Elle contient les bibliothèques GL, GLU et d’autres fonctions. Ainsi, lors de
l’élaboration d’un programme il suffit d’appeler glut.
• Elle est considérée comme une interface utilisateur plus élaborée. Elle peut être
utilisée avec différents langages : C++ (et C), FORTRAN et Ada
• le développement est à la version 3. Glut3 sera utilisée dans ce cours (la dernière
version 3.7 de GLUT date de novembre 2001)
• Comme Opengl, elle est libre d’utilisation et elle est distribuée gratuitement

2.5. DIVERS
• glu et glut sont les bibliothèques complémentaires les plus utilisées.
• Autres bibliothèques : glaux (Auxiliary Library), glui (extension de glut), …
• BRIAN Paul, un développeur très actif, a implanté une bibliothèque compatible et
similaire à OpenGL sous linux sous la dénomination mesa (cf. site mesa3d)
• Le développement d’applications en 3D est facilité par des bibliothèques plus
élaborées telles que « Open Inventor ». Elle facilite la modélisation des scènes et la
modélisation géométrique.

2.6. ORGANISATION DES BIBLIOTHÈQUES (GL, GLU, GLUT)


La présentation de la bibliothèque peut s’effectuer de plusieurs manières différentes. L’une
des méthodes consiste à considérer Opengl et ses bibliothèques complémentaires comme
une machine à états ou un moteur graphique (graphic engine). En effet, l’affichage d’une
scène est contrôlé par des variables dites d’état.
En adoptant cette méthode, les différentes actions sont regroupées en trois catégories, ou
moteurs, de fonctions :
1. Moteur géométrique (geometric engine) : Les fonctions de création d’objet ou
primitives
2. Moteur de numérisation (rastérisation) (raster engine) : numérisation de l’image
sous forme de fragments au niveau de la mémoire vidéo. Le fragment est
l’équivalent, au niveau de la mémoire, du pixel
3. Gestionnaire de numérisation (raster manager) : gestion des événements et de
l’affichage
2.6.1. Moteur géométrique (geometric engine)
Ce sous-ensemble de fonctions regroupe les primitives de modélisation et de création
géométrique de scènes 3D. Selon la nature des fonctions, elles se regroupent en trois
classes :
• Primitives Géométriques : fonctions de création d'objets élémentaires (points,
lignes, polygones, …)
• Modélisation et préparation de la visualisation : positionnement des objets dans
la scène 3D et emplacement du point de vision (l’observateur). En Opengl, le terme
caméra virtuelle est souvent adopté. Ces fonctions traduisent les transformations
infographie avec opengl 7
géométriques : translations, rotations, mise à l’échelle, projections, changement de
repère, …, etc.
• Modélisation des courbes et des surfaces par des NURBS.
2.6.2. Moteur de numérisation (raster engine)
C’est la catégorie des fonctions qui s’occupent de la numérisation des facettes de l’objet
pour produire l’équivalent des pixels appelés fragments. Il faut noter qu’on n’est pas
encore à la phase d’affichage. En effet, Opengl ne s’occupe pas de l’affichage de l’image
sur l’écran. Parmi les tâches des fonctions de ce groupe, citons :
• La technique des mémoires tampons (buffers) : Opengl utilise la technique dite
des buffers qui ne sont que des mémoires tampons. Ils seront détaillés
ultérieurement (§ buffers).
• La technique d’anti-crénelage (anti-aliasing) : c’est la technique qui permet
d’atténuer l’effet de l’approximation des lignes par des marches d’escaliers.
• L’élimination des parties cachées : l’élimination des parties cachées adoptée par
la bibliothèque opengl utilise l’algorithme de la normale (culling) et du Z-buffer
• Le codage des couleurs : Opengl utilise deux modes de codage de la couleur : le
mode RGBA (Rouge-Vert-Bleu-Alpha) ou le mode index de couleur
• La préparation du rendu d’une scène 3D (placage et projection de la texture) :
c’est les techniques qui permettent de donner un aspect réaliste aux surfaces d’objets
2D ou 3D.
• L’illumination (lumière et éclairage des matériaux) : Opengl dispose de fonctions de
visualisation qui tiennent compte des sources de lumière et des propriétés des
matériaux des objets de la scène. D’autres effets sont introduits pour rendre les
images plus réalistes. l’effet atmosphérique (brouillard, fumée ou voilage) est un
exemple de ces effets.
2.6.3. Gestionnaire de numérisation (raster manager)
Les fonctions de cet sous ensemble ne font pas partie intégrante d’Opengl. En effet, les
fonctions nécessaires à la visualisation, primitives d'affichage, sont fournies par les
bibliothèques complémentaires. Elles se chargent de l’affichage de l’image, créée au niveau
de la mémoire tampon (sous ensemble précédent), et effectuent les opérations sur les
pixels

2.7. FONCTIONS ET CONSTANTES

2.7.1. Syntaxe des fonctions et des constantes


Les fonctions et les constantes d’Opengl ou des autres bibliothèques ont une syntaxe qui
permet d’identifier leur nature et la bibliothèque d’appartenance.
La dénomination de chaque fonction débute par un préfixe, en minuscule, qui identifie la
bibliothèque (gl, glu, glut, …). Il est suivi du nom de la fonction avec la première lettre en
majuscule et d’autres suffixes.
Les constantes sont identifiées par le préfixe « GL_» suivi du nom de la constante et le tout
en majuscule. D’autres détails seront présentés ultérieurement (cf. la section suivante).
Exemple :
• fonction : glColor3f(1.0, 0.0, 0.0, 0.0)
• constante : GL_POINTS
2.7.2. Fonctions de création (ou Primitives graphiques)
Fonction vertex
infographie avec opengl 8
La fonction « vertex », sommet en anglais, est la primitive de base. À l’aide de cette
fonction plusieurs entités géométriques peuvent être créées : les points, les lignes, les
triangles ou les polygones. La syntaxe de la fonction est identique à celle décrite
précédemment avec l’ajout de paramètres spécifiant le type et le nombre d’arguments
passés à la fonction. Soit :

glVertex{1234}{le type}{v ou rien}(arguments)


• L’un des chiffres 1234 indique le nombre de composantes (x, y, z, w) qui seront passées
comme arguments à la fonction. Les sommets étant toujours repérés par les
coordonnées homogènes, les composantes non spécifiées sont prises égales aux
valeurs par défaut (0 pour les composantes y et z; 1 pour la quatrième w=1).
• Le paramètre {le type} indique le type des arguments passés à la fonction. En annexe,
nous donnons quelques types prédéfinis en Opengl avec leur type correspondant en
langage C.
• Si la lettre v (minuscule) est présente, elle indique que les arguments sont transmis
par pointeur (« vecteur »)
Exemples
• glVertex2f(1.0, 0.5); correspond au sommet (x=1.0, y=0.5, z=0 et w =1)
• glVertex3f(1.0, 0.5, 2.0); correspond au sommet (x=1.0, y=0.5, z=2.0 et w =1)
•la dernière définition est équivalente au deux instructions suivantes :
• float s[3]={1.0, 0.5, 2.0} ; glVertex3fv(s) ;
Remarque
• La syntaxe de glVertex est polyforme. Il existe plusieurs façons (64) de désigner un
vertex (sommet) : glVertex1f, glVertex2f, glVertex3f, …
Entités Graphiques Élémentaires
La notion d'objet, en programmation, n’est pas utilisée directement. L'interface propose
deux fonctions indiquant le début et la fin de la création de l’entité. Ainsi, la création de
l’objet suit les 3 étapes suivantes :
1. début de la création de la définition de l’objet : glBegin(enum code);
2. appels aux fonctions de création et de propriétés (exemple : glVertex*(x,y,z),
glColor*f(…))
3. fin de la définition dudit objet : glEnd()
La variable, code, passée en paramètre au début de la définition de l’objet, indique le type
de l'objet à construire. Les différentes valeurs sont données ci-dessous :

Constante (code) signification exemple


GL_POINTS suite de points non reliés
GL_LINES segments reliant chaque paire de points 0-1, 2-3, 4-5, …

GL_LINE_STRIP ligne brisée ouverte 0-1-2-3-4-…

GL_LINE_LOOP ligne brisée fermée 0-1-2-3-4-…-n-0

GL_TRIANGLES Triangles formés par chaque triplet 0-1-2-0, 3-4-5-3, …

GL_TRIANGLE_STRIP suite de triangles connectés par un coté 0-1-2-0, 1-3-2-1,


(attention à l'ordre des points) 2-3-4-2, …
er
GL_TRIANGLE_FAN éventail de triangles connectés par le 1 0-1-2-0, 0-2-3-0,
sommet 0-3-4-0, …
GL_QUADS suite de quadrilatères 0-1-2-3-0, 4-5-6-7-4, …

GL_QUAD_STRIP Le segment présenté après le premier définit un 0-1-3-2-0, 2-3-5-4-2,


quadrilatère avec le précédent (attention à
infographie avec opengl 9
l'ordre) 4-5-7-6, …

GL_POLYGON Polygone de sommets 0 à N. 0-1-2-3-4-…-n-0

Remarques
• Si le nombre de points n’est pas suffisant pour construire l’objet indiqué par la variable
« code », les derniers points non utilisés seront ignorés. Par exemple, si le nombre de
points est cinq (0, 1, 2, 3, 4) et le code est « GL_TRIANGLES », le résultat sera le
triangle (0-1-2-0) et les points (3 et 4) seront ignorés.
• Avec l’option « GL_POLYGON», aucune primitive ne sera créée si le nombre de points
est inférieur à 3.
• Seul le traitement des polygones convexes est garanti par Opengl et surtout lors de la
création du rendu réaliste.
2.7.3. Fonctions entre begin et end
Liste
Pour les entités créées entre begin et end, d’autres propriétés, peuvent être attribuées à
chaque entité graphique en plus des coordonnées des sommets. Ces informations sont
spécifiées par fonctions spécifiques. Parmi les commandes qui peuvent être appelée entre
begin et end, les plus importantes sont:
Fonction signification
glVertex*() Coordonnées d'un sommet (cf. § vertex ci-dessus)
glColor*() Couleur de tracé (cf. § couleur ci-dessous)
glIndex*() Indexe de couleur de tracé
glNormal*() Vecteur normal à un sommet
glEvalCoord*() ; glEvalPoint*() Génération de coordonnées de la courbe activée
glCallList() ; glCallLists() Appel des listes d'affichage (cf. § liste d’affichage)
glTexCoord*() Coordonnées d'une texture
glMaterial*() Propriété du matériau d'un objet
glFogCoord*() Coordonnées du fog

La couleur
Opengl offre deux modes de spécification de la couleur : le mode RGB ou le mode indexé
(table des couleurs indexées).
Si le mode RGB est activé, la couleur du tracé est définie par la spécification des
composantes rouge, verte et bleue. La spécification est réalisée par l’appel de l’une des
fonctions suivantes selon le nombre et la nature des arguments passés à la fonction :
void glColor{3,4}{b s i f d ub us ui} {v ou rien} ( r, v, b, alpha);
Les arguments (r, v, b, alpha) (ou en terme de pointeur v) correspondent aux valeurs des
composantes red, green, blue et/ou du mélange alpha.
La valeur alpha (valeur de diffusion du matériau) du code RGBA correspond à la technique
du mélange alpha qui consiste à combiner la couleur d'un fragment en cours de traitement
avec celle d'un pixel déjà stocké dans le tampon d'image. Le paramètre alpha peut être
considéré comme un facteur d’opacité ou de transparence de l’objet (alpha=1 : objet
totalement opaque, alpha=0 : objet totalement transparent). Un exemple qui peut être
cité est l’affichage d’un objet derrière une vitre d’une autre couleur. Si la couleur de la
infographie avec opengl 10
vitre est bleue et celle de l’objet est rouge. Le mélange Alpha permet de simuler la
transparence de la vitre. L’objet affiché, vu à travers la vitre, aura la couleur violette
La couleur choisie est active pour tous les objets crées après l’appel de la fonction
glColor*(…) jusqu'au nouvel appel de la même fonction avec une autre couleur. La couleur
choisie n’est utilisée que si la gestion des lumières et des matériaux n'est pas active
valeurs des arguments RGB des
couleurs les plus courantes
R G B Couleur
0.00 0.00 0.00 Noir
0.00 0.00 1.00 Bleu
0.00 1.00 0.00 Vert
0.00 1.00 1.00 Bleu clair (cyan)
1.00 0.00 0.00 Rouge
1.00 0.00 1.00 Violet (magenta)
1.00 1.00 0.00 Jaune
1.00 1.00 1.00 Blanc
0.50 0.50 0.50 Gris
0.25 0.25 0.25 Gris clair
0.75 0.75 0.75 Gris foncé
La normale
Lors de la création d’une facette ou d’une surface, il est possible de définir la normale au
niveau de chaque sommet (vertex). Elle est utilisée pour les calculs d'éclairage. La
normale définie devient la normale courante. Elle n’est modifiée que par un autre appel.
La définition est effectuée par l’une des fonctions :
void glNormal3{bsidf}(x, y, z); ou void glNormal3{bsidf}v( *v);
Cet appel attribue à la normale courante le vecteur passé en argument sous forme de
composantes (x, y, z) ou sous forme de pointeur v. S’elle n’est pas spécifiée, sa valeur
prise par défaut égale au vecteur (0.0, 0.0, 1.0).
Exemple
Ces lignes de programme permettent de créer un polygone plein avec une couleur donnée
à chaque sommet. La bibliothèque s’occupe de l’interpolation des couleurs entre les
sommets.

void dessin() {
glBegin(GL_POLYGON);
glColor3f (1.0, 0.0, 0.0); glVertex3f( 1.0, 0.5, 0.);
glColor3f (0.0, 1.0, 0.0); glVertex3f( 0.0, 1.0, 0.);
glColor3f (0.0, 0.0, 1.0); glVertex3f(-1.0, 0.5, 0.);
glColor3f (1.0, 1.0, 1.0); glVertex3f(-1.0,-0.5, 0.);
glColor3f (1.0, 1.0, 0.0); glVertex3f( 0.0,-1.0, 0.);
glColor3f (0.0, 1.0, 1.0); glVertex3f( 1.0,-0.5, 0.);
glEnd();}

2.7.4. Autres primitives


La bibliothèque Opengl contient d’autres fonctions qui permettent de définir des objets
spécifiques.
Rectangle
Une autre façon de créer un rectangle en 2D consiste à faire appel à l’une des fonctions :
infographie avec opengl 11
void glRect{s, i, f ou d}(x1, y1, x2, y2); ou void glRect{s, i, f ou d}v(v1[2], v2[2]);

les coordonnées de la diagonale sont définies par (x1, y1, x2, y2) ou (v1[2], v2[2])
{s, i, f ou d} indique le type de paramètre passé à la fonction (§ 2.7.2)
L’objet crée par l’appel à la est le même que celui crée par la séquence ci-
fonction dessous
glRectf(x1, y1, x2, y2); glBegin(GL_POLYGON);
glVertex2f(x1, y1);
glVertex2f(x2, y1);
glVertex2f(x2, y2);
glVertex2f(x1, y2);
glEnd();

3. CRÉATION ET MANIPULATION DES SCÈNES

3.1. CRÉATION DE LA VUE À VISUALISER


La réalisation d’une scène 3D (création, manipulation et visualisation) suit, en général, les
cinq étapes suivantes:
1. Création et modélisation de la scène : la scène 3D, constituée d’objets à visualiser,
est modélisée (ou définie) dans le repère direct de l’espace utilisateur (ou repère du
monde selon la terminologie Opengl). Le positionnement des différents objets est
effectué à l’aide des transformations géométriques 3D. En infographie comme en
Opengl, la convention consiste à adopter un repère utilisateur (ou repère du monde)
dont l’orientation des axes est définie comme suit : l’axe x vers la droite, l’axe y vers
le haut et l’orientation de l’axe z est choisie pour que le repère soit direct.
2. Choix du point de vision qui correspond à l’emplacement de l’observateur. En Opengl,
le point de vision est déterminé par la position et l’orientation de la caméra virtuelle.
À cette étape un autre repère indirect, lié à la caméra virtuelle, est défini. Les
coordonnées de la scène modélisée sont déterminées par rapport à ce nouveau
repère indirect.
infographie avec opengl 12
3. Projection et fenêtrage (opération fenêtrage en 3D) : L’étape consiste à éliminer les
parties de la scène situées en dehors du volume visualisé. Ce volume est défini lors
de la définition de la transformation de projections (cf. § transformations de
projections). Les entités ou leurs parties, contenues dans le volume de visualisation,
sont projetées sur le plan de projection (2D). Notons que l’opération fenêtrage 2D
est réalisée lors du fenêtrage 3D.
4. Cadrage et numérisation : Pour préparer l’affichage, la scène projetée est
transformée en fragments. L’opération consiste à transformer les coordonnées des
points de la scène projetée, par rapport au repère du plan de projection, en
coordonnées d’affichage. Elle est réalisée en effectuant la correspondance entre la
fenêtre utilisateur et la fenêtre d’affichage (appelée en Opengl « cadrage »).
5. Affichages et visualisation : C’est la dernière étape qui correspond à l’affichage des
images dont les fragments sont calculés précédemment. Rappelons que la
bibliothèque Opengl ne s’occupe pas de l’affichage de l’image. La tâche est confiée à
l’une des bibliothèques complémentaires.
Le principe de réalisation d’une scène, décrit précédemment, est schématisé au tableau ci-
dessous en indiquant les opérations et les transformations utilisées pour passer d’une étape
à une autre. Le repère des coordonnées utilisé à chaque étape est précisé.

Spécification de l’objet dans


l’espace utilisateur (monde en Repère utilisateur XO=(x, y, z, w)
Opengl)
Modélisation et Emplacement du point de vision
Changement de repère
Matrice (GL_MODELVIEW) (Mv)
modifiable par l’utilisateur
Spécification de l’objet dans le Repère indirect lié à la caméra (repère vision)
repère observateur XE = (x, y, z, w)

Transformation de projection et
spécification du volume visualisé
Matrice (GL_PROJECTION) (Mp)
modifiable par l’utilisateur
Spécification de l’objet projeté Repère de la caméra (ou position l’observateur)
et fenêtrage XP = (x, y, z, w)

Division des coordonnées par la quatrième


coordonnée Matrice Mn
traitement en interne

Normalisation des coordonnées XN = (x, y, z, 1)

Correspondance entre la fenêtre utilisateur et la


fenêtre d’affichage Matrice Mw
traitement en interne
Cadrage : spécification de
l’image dans la fenêtre Repère de la fenêtre d’affichage Xw = (x, y, z)
d’affichage z est utile lors de l’élimination des parties cachées
infographie avec opengl 13
À chaque étape correspond une matrice. Ainsi, chaque étape peut être mise en œuvre par
un produit matriciel. La réalisation de l’image se traduit par les opérations matricielles
suivantes :

X =M X →X =M X →X =M X →X =M X
v
v
o p
p
v n
n
p w
w
n

Soit

X =M M M M X
w
w n p v
o

Notons que seules les matrices de modélisation/visualisation Mv et de projection Mp sont


spécifiées directement par le programmeur. Les autres sont déterminées indirectement,
par la bibliothèque, lors de la définition des différents paramètres de la scène.

3.2. PRÉSENTATION DES MATRICES D’OPENGL


De la création à la visualisation, sans omettre la manipulation ou l’animation des objets et
des scènes, les transformations jouent un rôle très important. Comme il a été mentionné
au cours d’infographie, les coordonnées homogènes sont utilisées. Les transformations
géométriques sont définies par des matrices 4x4 de réels (4x4 de float).
Les opérations, utilisées durant les différentes étapes de la création d’une scène 3D
décrites précédemment, sont regroupées en 4 Transformations :
1. Modélisation (Model) : consiste à créer la scène en choisissant l’emplacement et
l’orientation des objets qui la composent
2. Visualisation (View) : détermine la position et l'orientation de la caméra virtuelle
3. Projection (Projection) : définit les caractéristiques de la caméra virtuelle (angle
d'ouverture, type de projection, ...) et la fenêtre utilisateur
4. Affichage (Viewport) : détermine la taille et la position de l'image sur la fenêtre
d'affichage. Une fois la fenêtre d’affichage définie par la fonction correspondante, la
fenêtre utilisateur étant définie par la projection, le cadrage est effectué par la
bibliothèque complémentaire utilisée
Les 3 premières transformations sont spécifiées directement par le programmeur. La
quatrième est déterminée, par la bibliothèque utilisée en tenant compte des premières.
En Opengl, trois matrices, correspondant aux transformations précédentes, sont
introduites. Chaque matrice est désignée par un paramètre sous forme d’un pointeur vers
un vecteur à 16 éléments où sont rangés les éléments de la matrice colonne par colonne.
Nous les désignerons avec le pointeur, prédéfini en Opengl, correspondant, soit :
1. GL_MODELVIEW : matrice de modélisation et de visualisation (model and view) ou
matrice de positionnement de la scène ou de la vision.
C’est une matrice de changement de repère : son rôle principal est le
positionnement des objets et de la scène dans l’espace utilisateur (le monde)
Il faut éviter de la considérer comme matrice de positionnement de la caméra,
même si indirectement c’est aussi son rôle. Elle permet, indirectement, de fixer la
position et l'orientation de la caméra virtuelle
Elle est appliquée à tous les sommets qui seront définis après son initialisation
2. GL_PROJECTION : matrice de projection. La transformation, correspondant, à cette
matrice permet de spécifier d’autres caractéristiques de visualisation de la scène :
Le mode de projection (type, centre, plan, …)
Le volume visualisé (fenêtre utilisateur en 3D)
les caractéristiques optiques de la caméra virtuelle (angle d'ouverture, ...)
3. GL_TEXTURE : matrice de gestion de la texture.
Elle n’est jamais utilisée directement
infographie avec opengl 14
Elle ne sera pas traitée dans cette section (cf. § texture).
Les deux premières matrices sont gérées et manipulées par les mêmes fonctions. Notons
qu’il n’est possible de manipuler et de modifier qu’une seule matrice à la fois. La matrice
désignée devient la « matrice courante » ou la « matrice active ». Les fonctions de gestion
de ces matrices sont :
• void glMatrixMode(pointeur_matrix); active la matrice désignée par l’un des pointeurs
(GL_MODELVIEW ou GL_PROJECTION) et la rend matrice courante.
• void glLoadIdentity(); initialise la matrice courante à l’identité. Il est conseillé de faire
appel à cette fonction après l’activation de chaque matrice par glMatrixMode() et avant
l’appel des différentes transformations géométrique.
• void glLoadMatrix{fd}(const Type pointeur_matrix_user); initialise la matrice courante à la
matrice définie par le paramètre pointeur_matrix_user qui est un pointeur vers un
vecteur à 16 éléments ou sont rangés les éléments de la matrice colonne par colonne
(à définir par le programmeur). Le type des éléments est défini par « type ». Elle
permet de définir les transformations non prédéfinies par les bibliothèques.
• void glMultMatrix{fd}(const type pointeur_matrix_user); effectue la multiplication, à droite
(McxM), de la matrice courante par celle définie par le paramètre pointeur_matrix_user.
Cette procédure est rarement utilisée. Comme mentionné en infographie, il est
préférable d’obtenir la transformation désirée par la combinaison des transformations
élémentaires : rotations, translations, …
• void glPushMatrix(); et void glPopMatrix(); fonctions de gestion de la pile des matrices
(cf. § pile des matrices)
Exemple
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
glTranslate();
glRotate();

3.3. TRANSFORMATIONS
3.3.1. Principes
Les transformations sont appliquées selon les principes fondamentaux suivants :
• La transformation affecte tous les objets définis après l’appel de la fonction
correspondante. Les objets déjà crées (ou définis) ne subiront aucune transformation.
• Les transformations effectuent un changement du repère courant. Il faut en tenir
compte lors de la composition des transformations. Par exemple, si on effectue une
rotation autour de l'axe x suivie d’une rotation autour de l'axe y, cette dernière
s'effectuera autour du nouvel axe y modifié par la première rotation.
3.3.2. Positionnement des objets (transformations élémentaires)
Le positionnement et l’animation des objets d’une scène ou de la scène elle-même sont
réalisés par différentes transformations géométriques. En Opengl plusieurs transformations
affines élémentaires sont prédéfinies et programmées en fonctions :
• void glRotate{f, d} (angle, xd, yd, zd) : l’appel de cette fonction, permet de multiplier la
matrice active par la matrice d’une rotation d’angle « angle » (en degré) autour de l’axe
passant par l’origine du repère courant et de direction le vecteur (xd, yd, zd)
• void glTranslate{f, d}(tx, ty, tz) : l’appel de cette fonction, multiplie la matrice active par
la matrice de la translation de vecteur (tx, ty, tz).
• void glScale{f, d}(cx, cy, cz) : multiplie la matrice courante par la matrice du
changement d’échelle de coefficients (cx, cy, cz) et de centre l’origine du repère courant.
• void glLoadMatrix(pointeur_matrix_user) : comme il a été mentionné précédemment,
cette fonction permet de spécifier la transformation directement par sa matrice. Avec
infographie avec opengl 15
cette technique on peut définir n’importe quelle transformation sans garantie qu’elle
soit affine.

3.4. PILE DES MATRICES


Après une série de transformations, l’avant dernière configuration de la scène peut être
obtenue en appliquant l’inverse de la dernière transformation. Ceci exige l’inversion de la
matrice de ladite transformation. Ce calcul peut s’avérer fastidieux. Opengl offre une
méthode plus simple et efficace qui nécessite moins de temps.
À chacune des trois matrices, définies précédemment, Opengl associe une pile. La pile est
un mécanisme de stockage qui consiste en un empilement de matrices en se basant sur la
technique Lifo (Last in first out). La matrice courante, qui peut être modifiable, est en haut
de la pile. L’avant dernière est au-dessous de celle-ci. Selon la version d’Opengl, la pile
contient au moins 32 matrices. Sa gestion est réalisée par des fonctions d’empilement et
de dépilement sont :
• void glPushMatrix(void) : effectue une copie de la matrice courante et la place en haut
de la pile. Ainsi, les deux matrices au-dessus de la pile, la dernière (matrice courante)
et l’avant dernière, sont identiques.
• void glPopMatrix(void) : écrase la matrice courante et la remplace par l’avant dernière
sauvegardée au niveau de la pile.
Exemple : Pour que seul un groupe d’objet subisse la transformation spécifiée
(translation, rotation, …), il suffit de procéder de la manière de l’exemple ci-dessous. Les
quelques lignes permettent aux matrices actives d’avant et d’après la rotation d’être
identiques.
glPushMatrix() ;
glRotate3f(ax,ay,az) ;
objets à transformer;
glPopMatrix() ;

3.5. MATRICE « GL_MODELVIEW » (SPÉCIFICATION DU POINT DE VISION)


La matrice, désignée par ce pointeur, permet de positionner les objets d’une scène ou de
placer la caméra virtuelle. Par défaut, la caméra virtuelle est placée à l’origine du repère
en regardant dans la direction des z négatifs.
Le positionnement de la caméra, sur la scène, peut s’effectuer de deux façons. La
première technique, réalisée par une fonction de glut, consiste à repositionner la caméra et
son repère. La deuxième, utilisée par Opengl et que nous déconseillons, consiste à
positionner les objets par rapport à la caméra (cf. § positionnement des objets).

3.5.1. Positionnement de la caméra


La bibliothèque glu dispose d’une fonction permettant de modifier la matrice de
modélisation visualisation (GL_MODELVIEW) de manière très simple et très significative. Elle
modifie le point de vision en changeant la position de la caméra ainsi que son repère.
L’appel de la fonction s'accomplit comme suit :
void gluLookAt(xcam, ycam, zcam, xvise, yvise, zvise, xup, yup, zup)
Les neuf arguments, de type GLdouble, de cette fonction sont :
• (xcam, ycam, zcam) : coordonnées de la position de la caméra (l’observateur)
• (xvise, yvise, zvise) : coordonnées du point visé ou direction de l’observation
• (xup, yup, zup) : vecteur y (vecteur indiquant la "verticale" de la caméra)

Remarques
l’appel de la fonction doit suivre l’activation de la matrice (GL_MODELVIEW)
les neuf coordonnées sont exprimées dans le repère d’origine (espace utilisateur)
l’appel à cette fonction se fait en général au début de la création
Exemple
infographie avec opengl 16
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
gluLookAt(xcam, ycam, zcam, xvise, yvise, zvise, xup, yup, zup)
3.5.2. Positionnement de la scène et ses objets
Le positionnement des objets est effectué à l’aide de la matrice de modélisation et de
visualisation (GL_MODELVIEW). Cette matrice est modifiable par les matrices
correspondant aux transformations géométriques décrites précédemment. L’exemple ci-
dessous indique une manière d’opérer la modification en faisant subir au repère d’origine
les transformations suivantes : une translation; 2 rotations.
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
glTranslate(vx, vy, vz);
glRotate(ax, 1., 0., 0.);
glRotate(ay, 0., 1., 0.);
• La matrice est d’abord initialisée à l’identité et ensuite multiplier par les matrices les
transformations spécifiées.
• L’ordre de l’appel est très important car le produit matriciel n’est pas commutatif.

3.6. MATRICE « GL_PROJECTION » (PROJECTION ET FENÊTRAGE)


Cette matrice est d’une très grande utilité. En plus de la spécification du type de
projection, elle permet de définir d’autres paramètres nécessaires à la création de scènes
3D :
• le mode et le type de projection avec ses paramètres
• le volume de visualisation utilisé lors du fenêtrage 3D (clipping 3D)
• la fenêtre utilisateur, 2D, nécessaire à l’opération cadrage
• les caractéristiques optiques de la caméra virtuelle (angle d'ouverture, ...)
3.6.1. Projections prédéfinies
Dans cette section nous donnons les fonctions qui correspondent aux différentes
projections prédéfinies par l’Opengl et ses bibliothèques complémentaires. L’appel de la
fonction multiplie la matrice courante par la matrice de la transformation de la fonction
appelée.
• les coordonnées sont spécifiées dans le repère lié à la caméra.
• les arguments sont de type Gldouble pour toutes les fonctions de projection
Projection orthogonale Opengl
void glOrtho(x_gauche, x_droit, y_bas, y_haut, z_proche, z_loin);
Elle permet de spécifier une projection orthogonale. Elle est définie comme suit :

• direction de projection : axe oz de la caméra


• plan de projection : plan z = z _ proche
• fenêtre utilisateur : rectangle [x _ gauche , x _ droit ]× [y _ bas , y _ haut ] à z = z _ proche
• volume de visualisation : parallélépipède
[x _ gauche , x _ droit ]× [y _ bas, y _ haut ]× [z _ proche , z _ loin ]
• la condition : z_proche < z_loin doit être respectée
infographie avec opengl 17

Projection perspective d’Opengl


void glFrustum(x_gauche, x_droit, y_bas, y_haut, z_proche, z_loin);
Elle spécifie une projection perspective définie par les paramètres :
• Centre de projection : position de la caméra
• plan de projection : plan z = z _ proche
• fenêtre utilisateur: rectangle [x _ gauche, x _ droit ]× [y _ bas, y _ haut ] à z = z _ proche
• volume de visualisation : pyramide tronquée de sommet l’origine du repère de la
caméra et délimitée par les deux plans z = z _ proche et z = z _ loin dénommés plans
de fenêtrage proche et éloigné
• la condition : z_proche < z_loin doit être respectée
infographie avec opengl 18

Projection perspective glu


void gluPerspective(ouverture, ratio, zmin, zmax);
Cette projection perspective, de la bibliothèque glu, est définie par :
• Centre de projection : position de la caméra
• plan de projection : plan z = z min
Pour cette projection, le volume de visualisation est la pyramide tronquée :
• de sommet l’origine du repère de la caméra
• d'angle d’ouverture verticale l’angle «ouverture» en degré de 0 à 180°
• délimitée par les plans z = z min et z = z max (plans de fenêtrage proche et éloigné)
• fenêtre utilisateur : la base supérieure de la pyramide située au plan z = z min et de
rapport d’aspect (largeur/hauteur) égal à ratio
• la condition z min < z max doit être respectée
Projection par défaut
Si la transformation de projection n’est pas spécifiée, par l’utilisateur, elle est définie avec
les paramètres par défaut suivants :
• type de projection : projection orthogonale
• direction : l’axe oz de la caméra
• plan de projection : plan z = 0
• fenêtre utilisateur : rectangle [− 1, + 1]× [− 1, + 1] à z = 0 dans le repère de la caméra
• volume de visualisation : [− 1, + 1]× [− 1, + 1]× [0, + 1]
3.6.2. Exemple d’utilisation
La spécification du type de projection est effectuée par la spécification de la matrice
« projection » d’une manière similaire à celle de la matrice « vision-modélisation ». L’appel
de la fonction correspondant à la projection désirée est réalisé comme mentionné ci-
dessous :
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glOrtho (); /* si projection orthogonale */
glFrustum (); /* si projection perspective de gl */
gluPerspective(); /* si projection perspective de glut */

3.7. GESTION DES ENTRÉES (GLUT)


L’interaction avec l’utilisateur s’effectue par le clavier, la souris et/ou tout autre dispositif de
saisie (tablette graphique, joystick, …). Dans cette section, quelques possibilités, offertes
par la bibliothèque glut pour gérer ces interactions, sont décrites.

3.7.1. Le clavier
La gestion du clavier dépend de la nature de la touche utilisée. La bibliothèque glut
distingue deux types de touches : les touches simples (code ascii) et les touches spéciales
(touches de fonctions f1, f2, …, les flèches, Ctrl, Alt, …).
La fonction glutKeyboardFunc(), fonction de glut, indique la fonction utilisateur, reçue
comme argument, de gestion du clavier qui sera utilisée. Cette dernière doit être
développée et nommée par l’utilisateur. Son entête prend la forme : void
my_keyboardfunc(unsigned char key, int x, int y). Elle retourne le code ASCII de la touche
enfoncée dans la variable key et la position (x, y) de la souris. Lors de son écriture, il est
impératif que les arguments soient de la forme (unsigned char key, int x, int y).
infographie avec opengl 19
La fonction glutSpecialFunc() indique la fonction utilisateur, reçue comme argument, de
gestion des touches spéciales qui sera utilisée. Comme pour les touches simples, cette
dernière doit être développée et nommée par l’utilisateur. L’entête prend la forme : void
my_specialKeysFunc(int key, int x, int y). Elle retourne le code de la touche spéciale
enfoncée dans la variable key et la position (x, y) de la souris. Les arguments de la
fonction doivent, obligatoirement, prendre la forme : (int key, int x, int y).

3.7.2. La souris
La gestion des actions liées à l’utilisation de la souris est effectuée par plusieurs fonctions :
• glutMouseFunc() : Cette fonction de glut indique la fonction utilisateur appelée lorsqu'un
bouton de la souris est enfoncé ou relâché. La fonction utilisateur doit, obligatoirement,
avoir les arguments (int button, int state, int x, int y), où
button = {GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON} indique si le
bouton de la souris indiqué par la variable est enfoncé
state = {GLUT_UP ou GLUT_DOWN} indique l’état du bouton relâché ou enfoncé
x et y les coordonnées du curseur de la souris dans le repère de la fenêtre d’affichage
• glutPassiveMotionFunc() : Elle spécifie la fonction utilisateur appelée lorsque la souris
bouge. Les arguments de cette fonction utilisateur sont du type (int x, int y), où x et y
sont les coordonnées du curseur de la souris.
• glutMotionFunc() : même fonctionnalité que la fonction précédente, sauf que la fonction
utilisateur ne sera appelée que si la souris bouge et qu'un bouton est enfoncé
• glutEntryFunc() : Cette fonction, rarement utilisée, indique la fonction utilisateur à
appeler lorsque la souris sort ou entre dans la fenêtre d’affichage. La fonction utilisateur
ne reçoit qu'un paramètre, de type int, qui vaut GLUT_LEFT si la souris sort de la fenêtre
et GLUT_ENTERED si la souris entre dans la fenêtre.
3.7.3. Liste des boutons pour les trois fonctions
Dans le tableau ci-dessous nous donnons les valeurs de la variable key (ou autre dans le
cas de la souris) retournées lors de l’appel des fonctions de gestion du clavier et de la
souris
glutKeyboardFunc() glutSpecialFunc() glutMouseFunc()
code ASCII des GLUT_KEY_F1, GLUT_KEY_F2, GLUT_KEY_F3, GLUT_LEFT_BUTTON
touches du clavier GLUT_KEY_F4, GLUT_KEY_F5, GLUT_KEY_F6 GLUT_MIDDLE_BUTTON
GLUT_KEY_F7, GLUT_KEY_F8, GLUT_KEY_F9, GLUT_RIGHT_BUTTON
GLUT_KEY_F10, GLUT_KEY_F11, GLUT_KEY_F12 et
GLUT_KEY_LEFT, GLUT_KEY_RIGHT,
GLUT_DOWN, GLUT_UP
GLUT_KEY_UP, GLUT_KEY_DOWN,
GLUT_KEY_PAGE_UP, GLUT_KEY_PAGE_DOWN,
GLUT_KEY_HOME, GLUT_KEY_END,
GLUT_KEY_INSERT

3.7.4. divers
• glutGetModifiers() : Est une fonction d'état qui sert à détecter si les touches Ctrl, Alt ou
Shift sont enfoncées. Il ne faut l'appeler que dans une fonction utilisateur de gestion
du clavier ou de la souris. Elle ne nécessite aucun paramètre et renvoie un entier (int)
qui peut prendre l’une des valeurs {GLUT_ACTIVE_SHIFT, GLUT_ACTIVE_CTRL,
GLUT_ACTIVE_ALT}.
• Autres dispositifs : La bibliothèque glut contient des fonctions pour gérer les entrées
par d’autres dispositifs tels que : les joysticks, les tablettes graphiques, …
3.7.5. Exemple
Nous donnons ci-dessous un exemple d’utilisation de la fonction de gestion des touches
spéciales. La fonction utilisateur permet de modifier l’angle de rotation autour de l’un des
axes selon la touche flèche enfoncée. Ces angles seront utilisés au niveau de la fonction de
infographie avec opengl 20
création de l’objet. Cet exemple sera repris ultérieurement (cf. Exemples de
programmation)

La fonction main contient la ligne suivante :


glutSpecialFunc(rotationParFleche); /*spécification la fonction utilisateur */
et la fonction utilisateur peut être définie comme suit :
void rotationParFleche(int k, int x, int y) ; /* fonction utilisateur */
{ switch(k) {
case GLUT_KEY_UP: rX = (rX + 5) % 360; break; /* rotation de 5° vers le haut */
case GLUT_KEY_DOWN: rX = (rX - 5) % 360; break; /* de 5° vers le bas */
case GLUT_KEY_RIGHT: rY = (rY + 5) % 360; break; /* de 5° vers la droite*/
case GLUT_KEY_LEFT: rY = (rY - 5) % 360; break; /* de 5° vers la gauche*/
default: break; }
glutPostRedisplay(); /* actualisation de l'affichage */ }

4. ORGANISATION D’UN PROGRAMME GRAPHIQUE

4.1. ÉTAPES DE PROGRAMMATION


La programmation suit les mêmes étapes que celles décrites précédemment pour la
création d’une scène 3D. Ainsi, un programme graphique de création suit les étapes :
1. Initialisation (initialisation des bibliothèques et de la fenêtre d’affichage; définition
des paramètres du dessin : la couleur du fond, la méthode du rendu, …)
2. Définition de la matrice de modélisation et de visualisation « GL_MODELVIEW »
3. Définition de la matrice de projection « GL_PROJECTION »
4. Définition de la scène : Création d'objets à partir de primitives simples d’Opengl ou
de fonctions plus élaborées des bibliothèques complémentaires
5. Rendu de l'image dans le buffer. Rappelons qu’Opengl ne s'occupe pas de l’affichage
de l'image sur l'écran. Pour s'assurer que les calculs sont terminés et que l'image
finale est calculée, il faut appeler une fonction de terminaison des calculs « void
glFlush () »
6. Gestion des événements (Affichage de l’image, animation, …) : les fonctions de
réalisation de cette gestion font partie de l’une des bibliothèques complémentaires.
Dans le présent document nous présenterons les fonctions de la bibliothèque glut.

4.2. INITIALISATION
4.2.1. Initialisation des états de glut
Fonctions
Lors de l’utilisation de la bibliothèque glut, l’initialisation est effectuée par la fonction :
void glutInit(int **argcp, char **argv);
argcp un pointeur vers une variable de main non modifiable
argv variable de main non modifiable
Elle se charge d’initialiser les variables d’états de glut. Notons que seules les fonctions
préfixées par glutInit peuvent la précéder. Il est vivement conseillé de l’appeler la
première.
Pour ne pas utiliser les valeurs par défaut, d’autres variables de l’environnement de
réalisation de l’image peuvent être initialisées. Parmi les fonctions d’initialisation, fournies
par la bibliothèque, et les plus utilisées, citons :
• void glutInitWindowPosition(int x, int **y); permet de positionner la fenêtre d’affichage
en spécifiant les coordonnées de son coin supérieur gauche (x, y) par rapport au coin
supérieur gauche de l’écran. Notons que pour la bibliothèque glut, l’origine de l’écran
est au coin supérieur gauche et que pour Opengl il est au coin inférieur gauche.
infographie avec opengl 21
• void glutInitWindowSize(int width, int **height); spécifie la taille (largeur et hauteur) de
la fenêtre d’affichage ((width, height en pixel)
• void glutInitDisplayMode(unsigned int mode); permet d’initialiser le mode d’affichage
défini par la valeur du masque mode. Plusieurs valeurs, séparées par le caractère
«|», peuvent être spécifiées lors de l’appel de la fonction. Les valeurs du masque sont
données en annexe (exemple : mode des couleurs : RGBA ou mode indexée, les
tampons mémoires, …).
• int glutCreatWindow(char *string) : crée une fenêtre avec les paramètres spécifiés par
les fonctions précédentes. Elle renvoie un identifiant unique identifiant la fenêtre
créée. la fenêtre ne sera affichée qu’après l’appel de glutMainLoop()
Exemple
La fonction main prend la forme :
int main(int argc, char **argv) ;
int windowname;
Le premier appel est celui de la fonction d’initialisation de la bibliothèque
glutInit(&argc, argv);
suivi d’appels de fonctions d’initialisation
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(sizex, sizey);
windowname = glutCreateWindow(" dessin rectangle ");
Nous conseillons de les rassembler dans une fonction utilisateur dédiée à l’initialisation et
de déclarer la variable windowname comme une variable globale. Elle contient le nom de la
fenêtre d’affichage qui servira à la gestion de celle-ci (redimensionnement, fermeture, …).
La variable peut être omise et le dernier appel devient :
glutCreateWindow(" dessin rectangle ");

4.2.2. Initialisation des Paramètres du dessin (ou des variables d’états)


L’Opengl étant considéré comme une machine qui calcule les états « state machine », les
dessins disposent d’une multitude de paramètres (variables d’état ou propriétés). Ces
derniers s’appliquent à tous les objets et scènes crées après la spécification desdits
paramètres. Ils restent applicables tant qu’un autre appel ne les modifie pas.
Ces paramètres sont très nombreux, nous n’allons en cités que quelques uns parmi les plus
utilisés. Pour plus d’informations, le lecteur peut consulter la liste complète en annexe du
document officiel des spécifications d’Opengl (cf. site officiel).
Paramètres généraux
Certains paramètres sont spécifiés par des fonctions dédiées. La plupart des autres
options, utilisées pour le rendu de l'image, sont activées ou désactivées par des fonctions
d’activation ou de désactivation. Parmi le premier ensemble nous citons :
• glClearColor(GLfloat R, GLfloat G, GLfloat B, GLfloat A); vide et rempli le buffer avec la
couleur spécifiée par les arguments
• glPointSize(GLfloat pixel_size); spécifie la taille du point (par défaut 1 pixel) et du lissage
• glLineWidth(Glfloat line_width); épaisseur du tracé d’une ligne (par défaut 1 pixel)
d’autres fonctions seront explicitées au fur et à mesure de l’introduction de la propriété
considérée (cf. § paramètres des polygones).
La plupart des autres paramètres sont activés ou désactivés par les deux fonctions :
• void glEnable (Glenum state_parameter) : active la propriété
• void glDisable (Glenum state_parameter) : désactive la propriété
où le paramètre state_parameter correspond à la propriété à activer ou à désactiver.
infographie avec opengl 22
les paramètres d’antiliasing et du motif du tracé de la ligne sont parmi les propriétés qui
sont spécifiées de cette manière.
Motif du tracé de la ligne
La fonction de définition du motif du tracé de lignes est :
glLineStipple(GLint facteur, GLushort motif);
• l’argument « motif» est une série de 16 bits où les 1 représentent les pixels allumés
et les 0 les pixels non modifiés (1 => pixel allumé; 0 => éteint)
• l’argument «facteur» est un entier de 1 à 255 précisant le facteur d’échelle motif
Ce mode est activé ou désactivé par:
glEnable(GL_LINE_STIPPLE) ou glDisable(GL_LINE_STIPPLE)
exemple
glLineStipple(2, 0x3F07);
(0x3F07 ≡ 0011 1111 0000 0111 correspond au motif 2x3 on – 2x5 off – 2x6 on – 2x2 off)
(de droite à gauche)
Paramètres d’antialiasing
L’antialiasing (anti-crénelage) est activé ou désactivé par les deux fonctions décrites ci-
dessus en utilisant l’une des constantes suivantes :
GL_POINT_SMOOTH, GL_LINE_SMOOTH, et GL_POLYGON_SMOOTH
Paramètres des polygones
Deux paramètres sont spécifiés avant la définition et la création des polygones (au sens le
plus large du terme). Ces paramètres s’appliquent à toutes les entités géométriques en
forme de polygone qui suivent l’appel de la fonction qui permet de les spécifier :
• glPolygonMode(Glenum face, Glenum mode)
face : pour chaque facette d’un polygone, on définit deux faces (la face de devant et la
face arrière) : la face de devant est celle dont les points, délimitant la facette, sont vus par
l’observateur dans le sens trigonométrique (sens anti-horaire) (ce choix, par défaut, peut
être modifié par opengl). En opengl, il est possible d’associer à chaque face de la facette
un mode de dessin différent. La face concernée par le traitement est désignée par le
paramètre « face »de la fonction.
mode : le mode de dessin de la facette ou du polygone
Face signification mode signification
GL_FRONT Face de GL_POINT Dessin des sommets
devant seuls
GL_BACK Face arrière GL_LINE Dessin des arrêtes
seules
GL_FRONT_AND_BACK Les deux GL_FILL Dessin des facettes
faces remplies

Mode de lissage des facettes


Lors de l’affichage d’un objet 3D solide avec illumination deux modes de lissage sont
prédéfinis par Opengl :
• Lissage plat ou uni : correspond à un remplissage de la facette par la même
couleur avec les mêmes propriétés (intensité, teinte, …)
• Lissage de GOURAUD : les propriétés de remplissage, nécessaires à l’affichage
d’une facette, sont obtenues par l’interpolation des propriétés calculées aux sommets
de celle-ci. C’est le mode par défaut.
L’activation de l’un des deux modes est effectuée par l’appel de la fonction
infographie avec opengl 23
void glShadeModel(GLenum mode) ;
où le paramètre « mode » prend l’une des valeur : GL_FLAT: pour le mode uni ou
GL_SMOOTH: pour le mode GOURAUD

4.3. DÉFINITION DE LA MATRICE « GL_MODELVIEW »


cf. § transformations

4.4. DÉFINITION DE LA MATRICE « GL_PROJECTION »


cf. § transformations

4.5. DÉFINITION DES OBJETS À DESSINER


cf. § primitives et autres

4.6. GESTION DES ÉVÉNEMENTS (LES CALL-BACKS)


Après les étapes citées précédemment, on doit spécifier les fonctions à appeler selon les
événements qui se produisent. Ceci est réalisé par les fonctions de glut chargées de la
gestion des événements nommées les « callback ». Les plus utilisés sont :
• glutDisplayFunc(void(*func)(void)) : spécifie la fonction utilisateur qui s’occupe de
l’affichage graphique de la scène créée.
• glutReshapeFunc(void(*func)(int w, int h)) : indique la fonction utilisateur à appeler si la
fenêtre d’affichage doit être redimensionnée lors de l’exécution du programme.
Notons que le changement des dimensions de la fenêtre d’affichage par la souris est
une pratique courante sous le système Windows.
• glutKeyboardFunc(void(*func)(unsigned char key, int x, int y)) : (cf. § gestion des entrées)
• glutMouseFunc(void(*func)(int button, int state, int x, int y)) : (cf.§ gestion des entrées)
• glutMotionFunc(void (*func)(int x, int y)) : (cf. § gestion des entrées)
Les fonctions appelées peuvent changer à n’importe quel moment. Si la valeur NULL est
passée comme paramètre au lieu de la fonction à utiliser, le callback correspondant est
désactivé. Les adresses sont à NULL par défaut.
• glutMainLoop(); Cette fonction active le gestionnaire d'événements de glut qui n’est
qu’une boucle infinie d’événements contrôlés par les différents callbacks. L’appel doit
être l’avant dernier dans la fonction main() juste avant return 0;

4.7. LES BUFFERS (OU PLANS MÉMOIRE)


4.7.1. Les buffers
Les « buffers » ne sont que des mémoires tampons (ou plans mémoires) qui contiennent
les données nécessaires à Opengl. Les plus importants sont :
• « Color_Buffer » il correspond à ce qu’est affiché. Il est le buffer principal.
Opengl peut utiliser un seul buffer ou le « double-buffering ». Si la technique
« double-buffering » est activée, l’affichage n’est pas effectué directement sur
l’écran mais sur une mémoire tampon. Le buffer « COLOR_BUFFER » est dédoublé.
En utilisant le double tampon mémoire, l’image est construite sur le « back-buffer »
avant de l’afficher en intervertissant ce buffer avec le « front-buffer » qui correspond
à ce qui est affiché. La fonction de glut qui se charge de cette tâche est :
glutSwapBuffers(). Cette technique, très utile, permet d’éviter le clignotement lors
des animations
le programmeur travaille comme s’il dessinait toujours sur le même buffer
Autres buffers standards (revoir Opengl principe et astuces)
• « Depth-buffer » : dit aussi le z-buffer, il est de même taille mémoire que le color-
buffer. Il contient les profondeurs z des fragments de l’image. Cette profondeur est
infographie avec opengl 24
nécessaire lors de l’élimination des faces cachées par l’algorithme connu sous la même
dénomination du z-buffer. Il doit être effacé avec glClear.
• « Stencil-buffer » : stencil (pochoir, patron en français) ce plan mémoire permet
d’afficher d’autres scènes dans une portion de la fenêtre d’affichage
• « Accumulation-buffer » : permet de superposer (ou mélanger) un ensemble d’images
en mode RGBA (réalisation d’effets spéciaux, …)
4.7.2. Utilisation
En utilisant la bibliothèque glut, les buffers affectés à une fenêtre sont spécifiés par la
fonction d’initialisation. Pour activer, en plus du mode RGB, le double-buffer, le depth-
buffer et le stencil-buffer, la fonction d’initialisation est appelée comme suit :
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);

4.7.3. Effacement des buffers


L’effacement des buffers est réalisé par l’appel à la fonction glClear appliquée au buffer
considéré. Ainsi, son application au « COLOR_BUFFER » permet de remplir l’écran par des
pixels dont la couleur est spécifiée par la fonction glClearColor (le noir est la couleur opaque
est la valeur par défaut).
void glClear( GLbitfield buffer_mask );
buffer buffer_mask
Color_buffer GL_COLOR_BUFFER_BIT
Depth_buffer GL_DEPTH_BUFFER_BIT
Accumulation_buffer GL_ACCUM_BUFFER_BIT
Stencil_buffer GL_STENCIL_BUFFER_BIT
Comme la fonction précédente, glClear peut effectuer plusieurs effacements en un seul
appel

4.8. PROGRAMMES D’ILLUSTRATION


Nous présentons des programmes qui illustrent l’utilisation des différentes fonctions
introduites précédemment. Nous recommandons aux lecteurs de les exécuter tout en
modifiant les différents paramètres (taille de la clôture, mode du polygone, la projection, la
position de la caméra, la couleur, …) pour vérifier leur influence sur la scène ou l’image
affichée.

4.8.1. Squelette d’un programme


Nous donnons l’ossature type d’un programme en Opengl. Notons qu’elle n’est pas unique.
#include <GL/glut.h> /* contient déjà <GL/gl.h> et <GL/glu.h> */
int sizex, sizey;
void reshape(int w, int h);

void dessin() { /* inclure les instructions de création de la scène */ }

void affichage () { /* routine générale d'affichage */


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /*réinitialisation de l'affichage */
dessin();
glFlush(); glutSwapBuffers(); /* on rend le tracé visible */ }

void tache_fond () { /* inclure les opérations à exécuter en tâche de fond */ }

int main(int argc, char **argv) {


glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowPosition(100,100);
glutInitWindowSize(sizex, sizey);
glutCreateWindow(" titre de la fenêtre d’affichage ");

glutReshapeFunc(reshape);
glutDisplayFunc(affichage);
infographie avec opengl 25
glutIdleFunc(tache_fond);
glutMainLoop(); /* boucle des évènements */
return 0; }

void reshape(int w,int h) {


glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); /* matrice de projection */
glLoadIdentity();
/* inclure type et paramètres de la projection */
glMatrixMode(GL_MODELVIEW); /* matrice de modélisation */
glLoadIdentity();
gluLookAt( …. ); /* position de la caméra */ }
4.8.2. programme 1 : initialisation, polygone et interpolation des couleurs

#include <GL/glut.h> /* contient déjà <GL/gl.h> et <GL/glu.h> */


int sizex, sizey;
void Reshape(int w,int h);

void dessin() { /* création de la scène */


glBegin(GL_POLYGON);
glColor3f (1.0, 0.0, 0.0); glVertex3f( 1.0, 0.5, 0.); /* couleur et coordonnées du sommet */
glColor3f (0.0, 1.0, 0.0); glVertex3f( 0.0, 1.0, 0.);
glColor3f (0.0, 0.0, 1.0); glVertex3f(-1.0, 0.5, 0.);
glColor3f (1.0, 1.0, 1.0); glVertex3f(-1.0,-0.5, 0.);
glColor3f (1.0, 1.0, 0.0); glVertex3f( 0.0,-1.0, 0.);
glColor3f (0.0, 1.0, 1.0); glVertex3f( 1.0,-0.5, 0.);
glEnd();}

void affichage () { /* routine générale d'affichage */


glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* réinitialisation de l'affichage */
dessin();
glutSwapBuffers(); /* on rend le tracé visible */
glFlush();}

int main(int argc, char **argv) {


sizex=400; sizey=400; /* taille de la fenêtre d'affichage */
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowPosition(100,100); glutInitWindowSize(sizex, sizey);
glutCreateWindow(" Polygone & Interpolation des couleurs");
glutReshapeFunc(Reshape);
glutDisplayFunc(affichage);
glutMainLoop();
return 0;}

void Reshape(int w,int h) {


glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION); /* matrice de projection */
glLoadIdentity();
glOrtho(-2.0, 2.0, -2.0, 2.0, 5.0, 15.0); /* projection orthogonale */
glMatrixMode(GL_MODELVIEW); /* matrice de modélisation */
glLoadIdentity();
gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); /* position de la caméra */ }

4.8.3. programme 2 : cube, projections et rotations

#include <GL/glut.h>
int sizex, sizey, ortho = 1;
float rX=20, rY=40; /* angles de rotation initiales*/
void affichage ();
void Reshape(int width, int height);
void rotationParFleche(int k, int x, int y);

int main(int argc, char **argv) {


sizex=300; sizey=300;
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); /* initialisation */
infographie avec opengl 26
glutInitWindowPosition(100,100); glutInitWindowSize(sizex, sizey);
glutCreateWindow(" Cube: Projection Perspective rx=20 ry=40");
glutReshapeFunc(Reshape);
glutDisplayFunc(affichage);
glutMainLoop();
return 0; }

void dessin() /* création de la scène */ {


glLineWidth(4); glColor3f(0.0, 1., 0.); glutWireCube(4.0); } /* fonction cube prédéfinie de la scène */

void affichage () {
glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef((GLfloat)rX, 1.0, 0.0, 0.0); glRotatef((GLfloat)rY, 0.0, 1.0, 0.0); /* rotations de repère local */
dessin(); /* tracer la scène cube */
glPopMatrix();
glFlush(); glutSwapBuffers();}

void Reshape(int width, int height) {


glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); /* matrice de projection */
glLoadIdentity();
if (ortho) glOrtho(-4.0, 4.0, -4.0, 4.0, 5.0, 20.0); /* projection orthogonale */
else glFrustum(-4.0, 4.0, -4.0, 4.0, 5.0, 20.0); /* projection perspective */

glMatrixMode(GL_MODELVIEW); /* matrice de modélisation et de visualisation*/


glLoadIdentity();
gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } /* position de la caméra */

Projection orthogonale rx=20°, ry=40° Projection perspective rx=20°, ry=40°

4.8.4. programme 3 : touches spéciales : rotations par flèches

#include <GL/glut.h> /* contient déjà <GL/gl.h> et <GL/glu.h> */


int sizex, sizey, ortho = 0, solid = 0;
int rX = 0, rY = 0; /* angles initials de rotation */
void Reshape(int width, int height);

void dessin() { /* tracé de la scène */


glLineWidth(4); glColor3f(0.0, 1., 0.);
if (solid) glutSolidCube(4.0); else glutWireCube(4.0); }

void affichage () { /* routine générale d'affichage */


glClearColor(1.,1.,1.,1.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef((GLfloat)rX, 1.0, 0.0, 0.0); glRotatef((GLfloat)rY, 0.0, 1.0, 0.0);
dessin(); /* tracer l'objet */
glPopMatrix();
glFlush(); glutSwapBuffers(); } /* on rend le tracé visible */

void rotationsparfleches(int k, int x, int y) { /* fonction définissant l'action des touches speciales */
switch(k) {
infographie avec opengl 27
case GLUT_KEY_UP: rX = (rX+5) % 360; break; /* vers le haut */
case GLUT_KEY_DOWN: rX = (rX-5) % 360; break; /* vers le bas */
case GLUT_KEY_RIGHT: rY = (rY+5) % 360; break; /* vers la droite */
case GLUT_KEY_LEFT: rY = (rY-5) % 360; break; /* vers la gauche */
default: break;}
glutPostRedisplay(); } /* actualisation de l'affichage */

int main(int argc, char **argv) {


sizex=400; sizey=400;
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowPosition(100,100); glutInitWindowSize(sizex, sizey);
glutCreateWindow(" rotations par les flèches");
glutReshapeFunc(Reshape);
glutDisplayFunc(affichage);
glutSpecialFunc(rotationsparfleches); /* designation de la fonction utilisateur */
glutMainLoop(); /* boucle des évènements */
return 0;}

void Reshape(int width, int height) {


glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); /* matrice de projection */
glLoadIdentity();
if(ortho) glOrtho(-4.0, 4.0, -4.0, 4.0, 5.0, 25.0); /* projection orthogonale */
else glFrustum(-4.0, 4.0, -4.0, 4.0, 5.0, 25.0); /* projection perspective */
glMatrixMode(GL_MODELVIEW); /* matrice de modélisation */
glLoadIdentity();
gluLookAt(0.0,0.0,10.0,0.0,0.0,0.0, 0.0, 1.0, 0.0); } /* position de la caméra */
4.8.5. programme 4 : lumières et animation

#include <GL/glut.h>
int rx = 0, ry = 0, rz = 0;
static float blanc[]={1.0,1.0,1.0,1.0}; static float jaune[]={1.0,1.0,0.0,1.0};
static float cyan[]={0.0,1.0,1.0,1.0}; static float magenta[]={1.0,0.0,1.0,1.0};
static float rouge[]={1.0,0.0,0.0,1.0}; static float rougetransparent[]={1.0,0.0,0.0,0.1};
static float vert[]={0.0,1.0,0.0,1.0}; static float bleu[]={0.0,0.0,1.0,1.0};
static float noir[]={0.0,0.0,0.0,1.0}; static float grisTresFonce[]={0.1,0.1,0.1,1.0};
static float grisFonce[]={0.25,0.25,0.25,1.0}; static float grisMoyen[]={0.5,0.5,0.5,1.0};
static float grisClair[]={0.75,0.75,0.75,1.0}; static float jauneClair[]={0.75,0.75,0.0,1.0};
static float jauneFonce[]={0.5,0.5,0.0,1.0}; static float cyanonce[]={0.0,0.5,0.5,1.0};
static float magentaFonce[]={0.5,0.0,0.5,1.0}; static float rougeFonce[]={0.5,0.0,0.0,1.0};
static float vertFonce[]={0.0,0.5,0.0,1.0}; static float bleuonce[]={0.0,0.0,0.5,1.0};
static float brun[]={0.8,0.6,0.4,1.0}; static float rose[]={1.0,0.65,0.65,1.0};
static float roseFonce[]={0.6,0.25,0.25,1.0}; static float bleuCiel[]={0.5,0.5,1.0,1.0};
static float bleuCielFonce[]={0.25,0.25,0.5,1.0};

void affichage (void) {


GLfloat light0_position[] = { 3.0, 0.0, 0.0, 0.0 }; GLfloat light1_position[] = { 0.0, 3.0, 0.0, 0.0 };
GLfloat light2_position[] = { 0.0, 0.0, 3.0, 0.0 };
glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix() ;
glRotatef((GLfloat) rx, 1., 0., 0.); glRotatef((GLfloat) ry, 0., 1., 0.); glRotatef((GLfloat) rz, 0., 0., 1.);
glLightfv(GL_LIGHT0,GL_POSITION,light0_position);
glLightfv(GL_LIGHT1,GL_POSITION,light1_position);
glLightfv(GL_LIGHT2,GL_POSITION,light2_position);
glutSolidCube( 2.0);
glPopMatrix();
glFlush(); glutSwapBuffers() ; }

void reshape(int ww,int hh) {


glViewport(0,0,ww,hh);
glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-3,3,-3,3, 1,10);
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0); }

void idle(void) { rx= (rx + 1) % 360; ry= (ry - 1) % 360; rz= (rz - 1) % 360; glutPostRedisplay() ; }

int main(int argc,char **argv) {


glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowPosition(10,10); glutInitWindowSize(400,400);
infographie avec opengl 28
glutCreateWindow("Lumières et animation ");
glMaterialfv(GL_FRONT,GL_SPECULAR, noir); glMaterialfv(GL_FRONT,GL_SHININESS, noir);
glLightfv(GL_LIGHT0,GL_DIFFUSE, rouge); /* source de lumière 1 */
glLightfv(GL_LIGHT1,GL_DIFFUSE, vert); /* source de lumière 2 */
glLightfv(GL_LIGHT2,GL_DIFFUSE, bleu); /* source de lumière 3 */
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHT2);
glEnable(GL_DEPTH_TEST); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutDisplayFunc(affichage);
glutMainLoop(); return(0); }

Image prise à une position et des sources données

4.9. GESTION D'UN PROCESSUS EN TÂCHE DE FOND


4.9.1. Utilisation de la fonction
void glutIdleFunc(void *func(void));
Elle indique la fonction à exécuter en tâche de fond lorsqu’aucun événement n’est en
attente. Elle est souvent utilisée lors de la programmation d’une application avec des
animations. La fonction appelée se charge, généralement, de la modification des variables
de la fonction passée au callback glutDisplayFunc(). La seule fonction d’Opengl qui peut
être appelée par ce callback est la fonction glutPostRedisplay qui permet de redessiner la
fenêtre d’affichage en lui préservant ses paramètres initiaux.

4.9.2. Programme 5 : animation en tâche de fond


Le programme ci-dessous permet d’illustrer l’utilisation de la fonction de gestion de la tâche
de fond. L’exemple consiste à faire tourner en permanence un cube autour des axes x et
y.

#include <GL/glut.h>
int sizex, sizey, ortho = 1, solid = 0;
int rX = 0, rY = 0; /* angles initiales des rotations*/
void affichage ();
void Reshape(int width, int height);
void rotationxy();

int main(int argc, char **argv) {


sizex=400; sizey=400;
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowPosition(100,100); glutInitWindowSize(sizex, sizey);
glutCreateWindow(" Cube en rotation permanente ");
glutReshapeFunc(Reshape);
glutDisplayFunc(affichage);
glutIdleFunc(rotationxy); /* utilisation des flèches pour tourner l'objet */
glutPostRedisplay(); /* actualisation de l'affichage */
glutMainLoop();
return 0;}

void dessin(){ /* création de la scène */


glColor3f(0., 1., 0.); glLineWidth(4);
infographie avec opengl 29
if (solid) glutSolidCube(4.0); else glutWireCube(4.0);}

void affichage () {
glClearColor(1., 1., 1., 1.);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef((GLfloat)rX, 1.0, 0.0, 0.0); /* faire tourner le repère local autour de l'axe x */
glRotatef((GLfloat)rY, 0.0, 1.0, 0.0); /* faire tourner le repère local autour de l'axe y */
dessin(); /* tracer le cube */
glPopMatrix();
glFlush(); glutSwapBuffers();}

void Reshape(int width, int height){


glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (ortho) glOrtho(-4.0, 4.0, -4.0, 4.0, 5.0, 25.0); /* projection orthogonale */
else glFrustum(-4.0, 4.0, -4.0, 4.0, 5.0, 25.0); /* projection perspective */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); /* position de la caméra */ }

void rotationxy() { /* fonction utilisateur appelée lors */


rX = (rX + 1) % 360;
rY = (rY + 1) % 360;
glutPostRedisplay(); /* actualisation de l'affichage */ }

Image prise à une position donnée

4.10. LES LISTES D'AFFICHAGE


4.10.1. Définition
Une liste d'affichage est une suite de commandes OpenGL stockées pour être utilisée au
moment voulu. Lors de l’appel d’une liste d'affichage, les commandes sont exécutées dans
leur ordre au niveau de celle-ci.
Les listes permettent d’optimiser le temps de calcul et d'affichage en supprimant les calculs
redondants et principalement lors des opérations matricielles, des calculs de l’illumination
et de modèle d'éclairage, des calculs des propriétés des matériaux, des textures, …
Une liste d'affichage est une macro ainsi elle ne peut être ni modifiée ni paramétrée.
L’inconvénient qui peut découler de l’utilisation des listes d'affichage est que ces listes
peuvent nécessiter des espaces mémoire importants.

4.10.2. Syntaxe des commandes


• début de la définition d'une liste d'affichage: void glNewList(GLuint liste,GLenum
mode); liste: un entier positif qui permet d’identifier la liste, mode: GL_COMPILE ou
infographie avec opengl 30
GL_COMPILE_AND_EXECUTE (la première valeur permet seulement stocker la liste et
la deuxième de la stocker et de l'exécuter simultanément)
• fin de la définition de la liste d'affichage en cours de stockage : void glEndList(void);
• Exécution de la liste d'affichage référencée par liste void glCallList(GLuint liste);
• Autres Commandes auxiliaires : GLuint glGenLists(GLsizei nbre); permet d’alloue nbre
listes d'affichage contiguës, non allouées. L'entier retourné est l'indice qui donne le
début de la zone libre de références. GLboolean glIsList(GLuint liste1); retourne vrai si
le paramètre liste1 est utilisé pour une liste d'affichage sinon faux. void
glDeleteLists(GLuint lndex, GLsizei nbre); Détruit les nbre listes à partir de la liste
index.
• Commandes qui ne peuvent pas faire partie d’une liste d’affichage : glFlush();
glDeleteLists(); glSelectBuffer(); glFinish(); …(§ manuel officiel).
4.10.3. Exemple
Pour tracer un cercle unitaire, centré à l’origine en le représentant par un polygone régulier
de N sommets, on peut procéder de 2 façons : avec ou sans utilisation de la liste
d’affichage.
Programmation sans utilisation de la liste Programmation avec une liste d’affichage
#include <GL/glut.h>
#include <math.h>
float PI = 3.14159;
int i, N=15, sizex=400, sizey=400;
void Reshape(int w,int h);
void cercle() {
GLfloat xx, yy;
glNewList(1, GL_COMPILE ) ;
glBegin(GL_POLYGON) ;
for ( i = 0 ; i <= N ; i++ ) {
xx = cos(i*2*PI/N); yy = sin(i*2*PI/N);
glVertex2f(xx, yy) ; }
glEnd() ;
glEndList() ; }

void dessin() { void dessin() {


GLfloat xx, yy ; glCallList(1);}
glBegin(GL_POLYGON) ;
for ( i = 0 ; i <= N ; i++ ) {
xx = cos(i*2*PI/N); yy = sin(i*2*PI/N);
glVertex2f(xx, yy) ; }
glEnd() ;}

void affichage () {
glClearColor(1.0,1.0,1.0,1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor4f(0.0,1.0,0.0,1.0);

dessin(); cercle(); dessin();


glFlush(); glutSwapBuffers(); }
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowPosition(100,100);
glutInitWindowSize(sizex, sizey);
glutCreateWindow(" dessin cercle ");
glutReshapeFunc(Reshape);
glutDisplayFunc(affichage);
glutMainLoop();
return 0;}
void Reshape(int w,int h) {
glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION); glLoadIdentity();
infographie avec opengl 31
glOrtho(-2.0, 2.0, -2.0, 2.0, 5.0, 15.0);/* projection orthogonale */

glMatrixMode(GL_MODELVIEW); glLoadIdentity();
gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); }/* position de la caméra */

Sans l’utilisation d’une liste d’affichage, la programmation du tracé du cercle est inefficace
car tout appel à la fonction dessin() entraîne les calculs des sinus et cosinus. En adoptant la
technique des listes, les calculs sont effectués lors de la création de la liste. Pour tracer le
cercle, il suffit d’insérer l’appel à la fonction : glCallList(1) ;

4.11. LE BROUILLARD
4.11.1. Mise en œuvre
L’application du brouillard suit les étapes suivantes :
• glEnable(GL_FOG); glDisable(GL_FOG); activer ou désactiver le brouillard
• glFogfv(GL_FOG_COLOR, fogcolor); couleur du brouillard spécifiée par la déclaration
GLfloat fogcolor[4] = {0.5,0.5,0.5,1}; (gris )
• glFogi(GL_FOG_MODE, GL_EXP); spécification du type de brouillard : en Opengl, trois
modes sont prédéfinies : (GL_LINEAR, GL_EXP, GL_EXP2). Chaque mode correspond
à une équation de simulation du brouillard
• glFogf(GL_FOG_DENSITY, 0.35); affecte une valeur (0.35) à la densité (ou l’épaisseur)
du brouillard. L’argument varie entre de 0 à 1 (0 : pas de brouillard, 1 : objet
opaque)
• glHint(GL_FOG_HINT, GL_DONT_CARE); contrôle l’importance de la qualité de l’image
par rapport à la vitesse de calcul
• glFogf(GL_FOG_START, 1.0); définit la distance du début du brouillard (par défaut 0.0)
• glFogf(GL_FOG_END, 5.0); définit la distance de la fin du brouillard (par défaut 1.0)

pour ces deux dernières fonctions la distance est relative à la position de la caméra
• glClearColor (0.5, 0.5, 0.5,1); Changement de la couleur du fond. Il est préférable
qu’elle soit identique à la couleur du brouillard. En effet, seuls les objets sont affectés
et non le fond.
Plusieurs équations de simulation sont utilisées :

end − coordonnée − ( densité × coordonnée ) 2


f = , f = e − densité × coordonnée ou f = e
end − start
après l’activation, la couleur en mode RGBA est donnée par :

C = f ×C fragment
+ (1 - f) × C fog

4.11.2. Exemple
/* version améliorée du programme de démonstration du brouillard de Silicon
Graphics, Inc.*/
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
static GLint fogMode;

/ * inclure la définition des couleurs du programme 4 */

static float rotx = 0, roty = 0, rotz = 0, scale = 1.0;


static float mt[16];
float xmin=-2,xmax, ymin=-2,ymax, zmin= 8, zmax= 30, fog_densite = 0.09, z_camera=10;
int ortho=0;
infographie avec opengl 32
void reshape(int w,int h) {
glViewport(0,0,w,h); xmax=-xmin; ymax=-ymin;
if( w <= h) {ymin = ymin*(double) h/w; ymax = ymax*(double) h/w;}
else {xmin = xmin*(double) w/h; xmax = xmax*(double) w/h;}
glMatrixMode(GL_PROJECTION);glLoadIdentity();
if (ortho) glOrtho(xmin,xmax,ymin,ymax,zmin,zmax); else glFrustum(xmin,xmax,ymin,ymax,zmin,zmax);
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
glLoadIdentity();gluLookAt(0.0,0.0,z_camera,0.0,0.0,0.0, 0.0, 1.0, 0.0); } /* position de la caméra */

void fleches_fonction (int key, int x, int y) {


switch (key) {
case GLUT_KEY_LEFT : roty +=1 ; break;
case GLUT_KEY_RIGHT : roty -=1 ; break;
case GLUT_KEY_UP : rotx +=1 ; break;
case GLUT_KEY_DOWN : rotx -=1 ; break;
case GLUT_KEY_PAGE_UP : scale = 2.0*scale; break;
case GLUT_KEY_PAGE_DOWN : scale = 0.5*scale; break;
default: break;}
glutPostRedisplay();}

void myinit(void) {
GLfloat position[] = { 0.0,3.0,3.0,0.0 };
GLfloat local_view[] = { 0.0 };
glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS);
glLightfv(GL_LIGHT0,GL_POSITION,position);
glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER,local_view);
glFrontFace(GL_CW);
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE);
glEnable(GL_FOG); fogMode = GL_EXP;
glFogf(GL_FOG_START,1.0); glFogf(GL_FOG_END,25.0);
glFogi(GL_FOG_MODE, fogMode); glFogfv(GL_FOG_COLOR,grisMoyen);
glFogf(GL_FOG_DENSITY,fog_densite); glHint(GL_FOG_HINT,GL_DONT_CARE);}

void renderRedTeapot(GLfloat x,GLfloat y,GLfloat z) {


float mat[4];
glPushMatrix(); glTranslatef(x,y,z);
mat[0] = 0.1745F; mat[1] = 0.01175F; mat[2] = 0.01175F; mat[3] = 1.0F;
glMaterialfv(GL_FRONT,GL_AMBIENT,mat);
mat[0] = 0.61424F; mat[1] = 0.04136F; mat[2] = 0.04136F;
glMaterialfv(GL_FRONT,GL_DIFFUSE,mat);
mat[0] = 0.727811F; mat[1] = 0.626959F; mat[2] = 0.626959F;
glMaterialfv(GL_FRONT,GL_SPECULAR,mat);
glMaterialf(GL_FRONT,GL_SHININESS,0.6F*128.0F);
glColor4fv(blanc); glutSolidSphere(1.0, 20, 20);
glPopMatrix();}

void display(void) {
glClearColor(0.5,0.5,0.5,0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glScalef(scale, scale,scale); glRotatef(rotx,1.0,0.0,0.0);
glRotatef(roty,0.0,1.0,0.0); glRotatef(rotz,0.0,0.0,1.0);
renderRedTeapot(-4.0,-0.5,-1.0); renderRedTeapot(-2.0,-0.5,-2.0); renderRedTeapot(0.0,-0.5,-3.0);
renderRedTeapot(2.0,-0.5,-4.0); renderRedTeapot(4.0,-0.5,-5.0);
glPopMatrix();
glFlush(); glutSwapBuffers() ;}

void souris(int bouton,int etat,int x,int y) {


if ( ( bouton == GLUT_LEFT_BUTTON ) && ( etat == GLUT_UP ) ) {
if(fogMode == GL_EXP) {fogMode = GL_EXP2; printf("mode Fog GL_EXP2\n"); }
else if(fogMode == GL_EXP2) {fogMode = GL_LINEAR; printf("mode Fog GL_LINEAR\n");}
else if(fogMode == GL_LINEAR){fogMode = GL_EXP; printf("mode Fog GL_EXP\n"); }
glFogi(GL_FOG_MODE,fogMode);
glutPostRedisplay(); } }

int main(int argc,char **argv) {


glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(400,200); glutInitWindowPosition(50,50);
glutCreateWindow("Brouillard");
infographie avec opengl 33
myinit();
glutReshapeFunc(reshape);
glutSpecialFunc(fleches_fonction);
glutMouseFunc(souris);
glutDisplayFunc(display);
glutMainLoop();
return(0);}

4.12. PROGRAMME D’ILLUSTRATION DE L’ILLUMINATION


Exemple d’illustration de l’illumination et la transparence
#include <GL/glut.h>
int sizex, sizey, ortho = 0, solid = 1, z_buffer=1, rX = 0, rY = 0;
void Reshape(int width, int height);

/* inclure la définition des couleurs programme 4 */

void dessin() { /* tracé de la scène */


GLfloat rouge_alpha[] = {1.0, 0.0, 0.0, 1}, vert_alpha[] = {0.0, 1.0, 0.0, 0.5};
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,rouge_alpha);
if (solid) glutSolidCube(4.0); else glutWireCube(4.0);
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,vert_alpha);
glPushMatrix(); glTranslatef(3.0, 0.0, 0.0); if (solid) glutSolidSphere(2., 20, 20); else glutWireSphere(2., 10, 10);
glPopMatrix();}

void affichage () { /* routine générale d'affichage */


glClearColor(1.,1.,1.,1.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix(); glRotatef((GLfloat)rX, 1.0, 0.0, 0.0); glRotatef((GLfloat)rY, 0.0, 1.0, 0.0);
dessin();
glPopMatrix();
glFlush(); glutSwapBuffers(); }

void rotationsparfleches(int k, int x, int y) {


switch(k) {
case GLUT_KEY_UP: rX = (rX+5) % 360; break; /* vers le haut */
case GLUT_KEY_DOWN: rX = (rX-5) % 360; break; /* vers le bas */
case GLUT_KEY_RIGHT: rY = (rY+5) % 360; break; /* vers la droite */
case GLUT_KEY_LEFT: rY = (rY-5) % 360; break; /* vers la gauche */
default: break;}
glutPostRedisplay(); } /* actualisation de l'affichage */

void init(void) {
GLfloat light0_position[] = {3.0, 3.0, 3.0, 0.0};
glLightfv(GL_LIGHT0,GL_AMBIENT,noir); glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc);
glLightfv(GL_LIGHT0,GL_SPECULAR,blanc); glLightfv(GL_LIGHT0,GL_POSITION,light0_position);
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); }

int main(int argc, char **argv) {


sizex=400; sizey=400;
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowPosition(100,100); glutInitWindowSize(sizex, sizey);
glutCreateWindow(" transparence et rotations par les flèches");
init();
glutReshapeFunc(Reshape);
glutDisplayFunc(affichage);
glutSpecialFunc(rotationsparfleches);
glutMainLoop();
return 0;}

void Reshape(int width, int height) {


glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); glLoadIdentity();
if(ortho) glOrtho(-4., 4., -4., 4., 5., 25.); else glFrustum(-4., 4., -4., 4., 5., 25.); glMatrixMode(GL_MODELVIEW);
glLoadIdentity();gluLookAt(0., 0. ,10., 0. ,0. ,0. , 0., 1., 0.); }
infographie avec opengl 34
5. ÉLIMINATION DES PARTIES CACHÉES
En Opengl deux algorithmes d’élimination des parties cachées sont prédéfinis :
1. algorithme de la normale (culling)
2. algorithme du Z-buffer (depth-buffer)
Nous donnons ci-dessous une description sommaire des deux algorithmes ainsi que leur
mise en œuvre par les bibliothèques. Ils sont détaillés au cours d’infographie.

5.1. ALGORITHME DE LA NORMALE (CULLING)


5.1.1. Principe
L’algorithme de la normale permet d’éliminer les facettes planes dont la face frontale n’est
pas du côté de l’observateur. En Opengl, le culling utilise cet algorithme, pour ne dessiner
que les facettes pour lesquelles les points les délimitant ont le même sens spécifié (sens
des aiguilles d’une montre «clockwise» ou le sens inverse « counter-clockwise»). Les
facettes qui ne seront pas affichées sont spécifiées par la fonction glCullFace

5.1.2. Mise en œuvre par Opengl


Les fonctions de mise en œuvre de la technique du culling par Opengl sont :
• void glEnable / void glDisable(Glenum state_parameter) active ou désactive le culling si
l’argument de la fonction prend la valeur GL_CULL_FACE
• void glFrontFace(GLenum mode) spécifiée les faces, du polygone, qui seront
considérées comme frontales. L’argument mode peut prendre l’une des valeurs :
GL_CW (clockwise) ou GL_CCW : counter-clockwise
• void glCullFace(GLenum mode) indique la face qui sera éliminée par le culling (mode =
GL_FRONT, GL_BACK ou GL_FRONT_AND_BACK)
5.1.3. Remarques
• la technique utilisée par cet algorithme, dit de la normale, est très simple.
• Il n’élimine que toutes les facettes cachées d’un objet 3D convexe. Pour les objets
concaves, l’élimination est souvent partielles (§ cours infographie)
• Il est souvent utilisé comme ébauche aux autres algorithmes
• Lors de la définition et la création d’objets 3D, le programmeur doit veiller à ce que le
même sens soit adopté pour toutes les facettes
• La valeur par défaut de l’argument de la fonction glFrontFace() est GL_CCW

5.2. ALGORITHME DU Z-BUFFER (DEPTH-BUFFER)


L'algorithme d'élimination des parties cachées, Z-Buffer apparu au milieu des années 70,
permet de n’afficher que les parties, d’objets, visibles à l’observateur et non masquées par
d’autres objets ou par lui-même.

5.2.1. Principe et Implantation


• Le principe de l’algorithme Z-Buffer est de rechercher la profondeur (distance z entre
le point de vision et le point correspondant au pixel considéré) de tous les pixels de
mêmes coordonnées (x, y) ensuite de n’afficher que celui dont la profondeur
(coordonnée z) est la plus proche de l’observateur (la caméra)
• Deux zones mémoire sont définies : le premier, destiné à stocker la couleur de
chacun des pixels de l'image, est initialisé à la couleur de fond. Le deuxième, tampon
∞ (en partique une valeur très grande en valeur absolue), est
profondeur initialisé à -∞
destiné à stocker la profondeur écran maximum de chacun des pixels de l'image (ou la
distance minimale de l’observateur)
infographie avec opengl 35
• Décomposer chaque facette à afficher en pixels de coordonnées (x, y) en calculant,
lors de la décomposition, la profondeur écran z de chacun des pixels
• Comparer cette profondeur à la valeur correspondante au niveau du tampon
profondeur. Si cette profondeur est plus grande que la valeur déjà stockée dans le
tampon profondeur, on remplace cette dernière (l’ancienne valeur z dans le tampon
profondeur) par la nouvelle valeur et la couleur du pixel (x, y) du tampon couleur est
calculée en fonction de l’affichage (illumination, caractéristiques de la facette, …)
• Répéter le processus jusqu’au traitement de toutes les facettes
• Affichage de l’image
• L’algorithme ne doit pas être assimilé à un tri. En effet, le calcul du maximum pour
chaque pixel est effectué vis à vis de l'ensemble des pixels de tous les objets de la
scène à créer
5.2.2. Avantages
• Algorithme facilement programmable et notamment au niveau du matériel. Ses
performances sont mesurées en pixels/seconde, segments/s ou polygones/s.
• Il est en amélioration permanente et s’adapte bien au calcul parallèle.
• Il est relativement simple de le combiner avec l’algorithme d'illumination de Gouraud
et/ou du placage de la texture. Notons que les facettes sont souvent de type
triangulaire car elles sont faciles à numériser
• L’optimisation de l’algorithme est obtenue en utilisant des techniques incrémentales de
Bresenham (utilisation exclusive de variables entières et d'opérations simples)
• Il est très utilisé par les jeux et les logiciels de CAO.
5.2.3. Inconvénients
• Taille mémoire : Les deux mémoires tampons, buffers utilisés, peuvent avoir des
tailles très importantes plusieurs méga octets pour les grands écrans
• Temps de calcul et accès mémoire : La décomposition de chaque facette en pixels
nécessite une puissance de calcul importante et une vitesse d'accès mémoire très
élevée
• Adaptation : Il est difficilement adaptable aux phénomènes optiques complexes
5.2.4. Mise en œuvre par Opengl
• activer l’élimination des parties cachées par la fonction glEnable(GL_DEPTH_TEST); par
la modification de la variable d'état GL_DEPTH_TEST
• désactiver glDisable(GL_DEPTH_TEST);
• Lors de l’activation de cet algorithme, Z-buffer, l’effacement doit être effectué sur les
deux tampons (couleur et profondeur) entre chaque modification de l’image par la
fonction glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
• le Z-Buffer peut être activé et désactivé autant de fois que c’est nécessaire au sein
d’un même programme.

5.3. EXEMPLES DE PROGRAMMATION


La structure de fonction d’affichage est de la forme :
void affichage () { /* routine générale d'affichage */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /*réinitialisation de l'affichage*/
glEnable(GL_DEPTH_TEST);
dessin();
glDisable(GL_DEPTH_TEST);
5.3.1. programme 6: z_buffer
#include <GL/glut.h>
int sizex, sizey, ortho = 0, solid = 1, z_buffer=0;
infographie avec opengl 36
int rX = 35, rY = 45; /* angles des rotations*/
void affichage ();
void Reshape(int width, int height);

int main(int argc, char **argv) {


sizex=300; sizey=300;
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowPosition(100,100); glutInitWindowSize(sizex, sizey);
glutCreateWindow(" theière & cube avec z_buffer ");
glutReshapeFunc(Reshape);
glutDisplayFunc(affichage);
glutPostRedisplay();
glutMainLoop(); return 0;}

void dessin(){ /* création de la scène */


glColor4f(1.0, 0.5, 0.0, 1.0); if (solid) glutSolidTeapot(4.0); else glutWireTeapot(4.0);
glColor4f(0.0, 0.5, 0.5, 0.0);
glPushMatrix();
glTranslatef(0.0, 0.0, -5.5); if (solid) glutSolidCube(5.0); else glutWireCube(5.0);
glPopMatrix();}

void affichage () {
glClearColor(1.,1.,1.,1.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef((GLfloat)rX, 1.0, 0.0, 0.0); /* faire tourner le repère local autour de l'axe x */
glRotatef((GLfloat)rY, 0.0, 1.0, 0.0); /* faire tourner le repère local autour de l'axe y */
if (z_buffer) glEnable(GL_DEPTH_TEST); dessin(); glDisable(GL_DEPTH_TEST);
glPopMatrix();
glFlush(); glutSwapBuffers();}

void Reshape(int width, int height){


glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); glLoadIdentity();
if (ortho) glOrtho(-5.,5.,-5.,5., 5.,20.); else glFrustum(-5.,5.,-5.,5.,5.,20.);
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
gluLookAt(0., 0., 10., 0., 0., 0., 0., 1., 0.);}

Sans l’activation du z_buffer Avec l’activation du z_buffer


infographie avec opengl 37

6. ANNEXES

6.1. TYPES PRÉDÉFINIS


Le tableau ci-dessous donne quelques types prédéfinis par la bibliothèque Opengl :

Type en C Type prédéfini par OpenGL


signed char GLbyte
short GLshort
long, int GLint, GLsizei
float GLfloat, GLclampf
double GLdouble, GLclampd
unsigned char GLubyte, GLboolean
unsigned short GLushort
unsigned long GLuint, GLenum, GLbitfield
6.2. MASQUES DU MODE D’AFFICHAGE
Quelques valeurs du mask, utilisé comme argument de la fonction d’initialisation
glutInitDisplayMode(unsigned int mode) sont données au tableau ci-dessous

mode Signification
GLUT_RGBA le mode RGBA (valeur par défaut 1.0, 1.0, 1.0, 1.0)
GLUT_RGB le mode RGB (valeur par défaut 1.0, 1.0, 1.0)
GLUT_INDEX le mode index de couleur (ce mode est prioritaire)
GLUT_ALPHA composante alpha sur le tampon (ou les tampons) de
couleur
GLUT_SINGLE simple tampon (simple buffer) (c’est la valeur par défaut)
GLUT_DOUBLE double tampon double buffer (mode prioritaire que le
simple)
GLUT_ACCUM tampon à accumulation
GLUT_DEPTH tampon de profondeur
GLUT_STENCIL tampon pochoir (stencil)
GLUT_STEREO fenêtre stéréo
GLUT_LUMINANCE fenêtre stéréo avec un modèle de couleur « luminance »

6.3. LISTE DES FONCTIONS OPENGL, GLU ET GLUT


Nous donnons une liste non-exhaustive des fonctions d’Opengl et des bibliothèques
complémentaires les plus utilisées (glu et glut). Elles sont citées par ordre alphabétique

6.3.1. Bibliothèque gl
Liste des fonctions
1. glBegin 26. glGetBooleanv 51. glNormal
2. glBlendFunc 27. glGetDoublev 52. glOrtho
3. glCallList 28. glGetError 53. glPointSize
4. glClear 29. glGetFloatv 54. glPolygonMode
5. glClearColor 30. glGetIntegerv 55. glPolygonStipple
6. glClearDepth 31. glGetLight 56. glPopAttrib
7. glClipPlane 32. glGetMaterial 57. glPopMatrix
8. glColor 33. glInitNames 58. glPopName
9. glCopyPixels 34. glIsList 59. glPushAttrib
infographie avec opengl 38
10. glCullFace 35. glIsEnabled 60. glPushMatrix
11. glDeleteLists 36. glLight 61. glPushName
12. glDisable 37. glLightModel 62. glRasterPos
13. glDrawPixels 38. glLineWidth 63. glReadPixels
14. glEnable 39. glLineStipple 64. glRenderMode
15. glEnd 40. glLoadIdentity 65. glRotate
16. glEndList 41. glLoadMatrix 66. glScale
17. glEvalCoord1 42. glLoadName 67. glSelectBuffer
18. glEvalCoord2 43. glMap1 68. glShadeModel
19. glEvalMesh1 44. glMap2 69. glTexCoord
20. glEvalMesh2 45. glMapGrid1 70. glTexImage1D
21. glFinish 46. glMapGrid2 71. glTexImage2D
22. glFlush 47. glMaterial 72. glTexParameter
23. glFrontFace 48. glMatrixMode 73. glTranslate
24. glFrustum 49. glMultMatrix 74. glVertex
25. glGenLists 50. glNewList 75. glViewport
6.3.2. Bibliothèque glu
Liste des fonctions

1. gluBeginSurface 9. gluNewTess
2. gluEndSurface 10. gluErrorString
3. gluLookAt
4. gluNewNurbsRenderer
5. gluNurbsProperty
6. gluNurbsSurface
7. gluPerspective
8. gluPickMatrix
Objets 3D prédéfinis par glu
• glu permet de créer des objets quadratiques (sphère, cylindre, disque, …).
• Permet de créer des objets complexes à l’aide des NURBS ou mettre en œuvre une
technique de tesselation (triangulation)
La procédure de création de ces objets suit les étapes suivantes
1. GLUquadricObj *pObj; définition du pointeur d'objet à déclarer en global ou dans la
même fonction
2. pObj = gluNewQuadric(); Initialisation et création d'un nouvel objet (Retourne 0 si la
mémoire est insuffisante)
3. gluQuadricDrawStyle(Quadric1, mode); Le premier argument indique la quadratique à
créée. Le second est le mode d’affichage GLU_FILL : mode solide (mode par défaut),
GLU_LINE : mode filaire, GLU_POINT : mode point). L’appel de cette fonction peut se
faire avant chaque objet pour définir son mode d’affichage. Ainsi, les objets d’une
scène peuvent s’afficher en différents modes.
4. gluQuadricNormals(pObj, GLU_SMOOTH); application des normales
5. gluSphere (pObj, 10, 20, 30); appel de la fonction de création la sphère pour ce cas
6. gluDeleteQuadric (pObj); fin de création, destruction de l'objet et libération de la mémoire
infographie avec opengl 39
Fonction Description
gluCylinder(pObj, baseRadius, topRadius, height, Cylindre orienté le long de l’axe et de
slices, stacks);
base au plan z=0 (le cylindre n’est pas
fermé)
gluDisk (pObj, innerRadius, outerRadius, slices, Disque dans le plan z=0 (Slices : nombre
loops);
de secteurs, loops: nombre de cercles
concentriques)
gluPartialDisk(pObj, innerRadius, outerRadius, Portion du disque dans le plan z=0
slices, loops, startAngle, sweepAngle);
gluSphere (pObj, radius, slices, stacks); Sphère centrée à l’origine
• Les rayons, la hauteur et les angles sont de type GLdouble et les autres de type GLint.
• L’objet crée étant situé à l'origine, les transformations (translations, rotations, …)
permettent de le placer à l’emplacement voulu.
• Lors des tests, pour apprécier l’influence des différents paramètres, il est conseillé
d’opter pour l’affichage en mode filaire

6.3.3. Bibliothèque glut


Liste des fonctions

1. glutAddMenuEntry 18. glutKeyboardFunc 35. glutWireSphere


2. glutAddSubMenu 19. glutMainLoop 36. glutSolidSphere
3. glutAttachMenu 20. glutMotionFunc 37. glutWireCube
4. glutBitmapCharacter 21. glutMouseFunc 38. glutSolidCube
5. glutBitmapWidth 22. glutPassiveMotionFunc 39. glutWireTorus
6. glutCreateMenu 23. glutPopWindow 40. glutSolidTorus
7. glutCreateWindow 24. glutPositionWindow 41. glutWireCone
8. glutDestroyWindow 25. glutPostRedisplay 42. glutSolidCone
9. glutDisplayFunc 26. glutPostWindowRedisplay 43. glutWireTetrahedron
10. glutFullScreen 27. glutPushWindow 44. glutSolidTetrahedron
11. glutHideWindow 28. glutReshapeFunc 45. glutWireOctahedron
12. glutIconifyWindow 29. glutReshapeWindow 46. glutSolidOctahedron
13. glutIdleFunc 30. glutShowWindow 47. glutWireIcosahedron
14. glutInit 31. glutSpecialFunc 48. glutSolidIcosahedron
15. glutInitDisplayMode 32. glutStrokeCharacter 49. glutWireDodecahedron
16. glutInitWindowPosition 33. glutStrokeWidth 50. glutSolidDodecahedron
17. glutInitWindowSize 34. glutSwapBuffers 51. glutWireTeapot
52. glutSolidTeapot
Objets 3D prédéfinis dans glut
Des objets 3D sont prédéfinis par glut. Ils sont crées, centrés à l’origine, en mode filaire
(wire) ou solide (solid). Les fonctions de création sont de la forme :
void glut{mode}{objet}(arguments) ;
{mode} prend l’un des deux paramètre : Wire ou Solid
{objet} indique l’objet à créer : cone, icosahedron, teapot, cube, octahedron,
tetrahedron, dodecahedron, sphere, torus.
Exemple
glutWireCube(5.0) ; glutSolidCube(5.0) ;
infographie avec opengl 40
dessin d’un cube de 5 unités de côté et centré à l’origine en mode filaire ou solide.
objet fonction
Sphère glut{mode}Sphere(radius, slices, stacks) ;
Cube glut{mode}Cube(Gldouble size) ;
Tore glut{mode}Torus(innerRadius, outerRadius, sides, rings);
Cône glut{mode}Cone(base, height, slices, stacks);
Tétraèdre 4 faces glut{mode}Tetrahedron(void);
Octaèdre 8 faces glut{mode}Octahedron(void);
Icosaèdre 12 faces glut{mode}Icosahedron(void);
Dodécaèdre 20 faces glut{mode}Dodecahedron(void);
Théière glut{mode}Teapot(GLdouble size);
Les rayons et les hauteurs sont de type GLdouble et les autres de type GLint

6.4. DIVERS
6.4.1. versions et informations

const GLubyte glGetString(GLenum, name); Permet de retourner des informations concernant la version
de la bibliothèque utilisée. L’argument name peut prendre les valeurs :
• GL_VERSION retourne une chaîne de caractères qui permet d’identifier la version
• GL_VENDOR retourne le nom de la compagnie responsable de la version utilisée
• GL_RENDER retourne de la version utilisée
• GL_EXTENSIONS retourne de la version utilisée
• GLU_VERSION retourne une chaîne de caractères (string) qui permet d’identifier la version
• GLU_EXTENSIONS retourne de la version utilisée de glu
6.4.2. prochaine versions du document
Application de la texture, Affichage texte, glPolygonStipple(), ;
infographie avec opengl 41