Programmation avec OpenGL
Herve.Frezza-Buet@supelec.fr
Le cours via "glop"
La version moderne (orientée objet) de ce cours se trouve sur la page de glop. Le code y est plus clair que celui présenté ici.
Références
Mode d'emploi
Cette page contient des programmes, qui présentent progressivement
l'introduction des concepts OpenGL. Les changements d'un programme à
l'autre sont balisés par les commentaires suivants :
/* CHANGEMENT */
/* ###
*/
/* ###
*/
/* ####### */
/* #####
*/
/* ###
*/
/* #
*/
/* #
*/
/* ###
*/
/* #####
*/
/* ####### */
/* ###
*/
/* ###
*/
/* CHANGEMENT */
Les liens sur des sources à partir de cette page sont des liens
sur des fichiers html, vous pouvez télécharger l'ensemble
des fichiers C correspondants.
Pour compiler puis exécuter un fichier toto.c
contenant
du code OpenGL, il vous suffit sous linux de taper la commande de
compilation suivante :
gcc toto.c -lGL -lGLU -lglut
./a.out
Les librairies OpenGL
-
libGL : permet de dialoguer avec un serveur OpenGL.
-
libGLU : est un ensemble d'utilitaires (dessiner une sphère, ...).
-
libglut : permet d'interfacer rapidement, et de façon portable,
OpenGL et l'interface graphique dont votre système dispose.
Les constituants d'un serveur OpenGL
Les buffers
-
Un ou plusieurs Frame Buffers.
-
Un Accumulation Buffer.
-
Un Depth Buffer (dit z-buffer).
-
Un Stencil Buffer.
Les piles de matrice
-
La pile GL_MODELVIEW permet de stocker les transformations à
appliquer aux objets de la scène.
-
La pile GL_PROJECTION permet de stocker les transformations à
appliquer pour passer d'une scène dans un espace 3D à une
image 2D sur l'écran de l'ordinateur. Selon la projection utilisée,
on peut avoir différents types de perspective rendue.
Les textures
-
Il s'agit d'images destinées à être plaquées
sur les surface des objets, pour donner une impression de texture.
Les listes
-
Les listes permettent de stocker au niveau du serveur OpenGL des séquences
d'instruction que l'on utilise souvent. Appeler une liste est plus rapide
que de redonner au serveur l'ensemble des commandes qui la constituent.
Les sommets
-
Les sommets des polygones sont définis selon 4 coordonnées
x,y,z,w (dites coordonnées homogènes). La position d'un point
(x,y,z,w) dans l'espace 3D est (x/w,y/w,z/w).
Les couleurs
-
Les couleurs sont exprimées selon leurs composantes RGBA, R étant
la composante rouge, G la composante verte, B la composante bleue, et A
une composante ayant diverses interprétation selon les contextes
d'utilisation, une interprétation courante étant la transparence
de la couleur.
Démarrer... avec glut
BasicGlut.c
Mon premier programme !
-
6 plans de clipping sont ainsi définis.
-
Placement des objets
Pendule-1.c
Double buffering et z-buffer
-
Pour pas que ca clignote, on dessine dans un frame buffer (BACK) et on
le permute avec leui affiché quand le dessin est terminé.
-
En ce qui concerne la gestion de la profondeur des objets, on met en place
le test de profondeur basé sur le z-buffer.
Pendule-1-1.c
Transparence, utilisation du blending (to blend = se fondre)
-
Le bending pemet, au lieu d'écraser les couleurs du frame buffer
quand on y dessine, de mélanger les couleurs que l'on dessine avec
celles déjà présentes. Pour que le pendule soit transparent,
il faut :
-
Dessiner tout ce qui n'est pas transparent
-
Interdire le z-buffer en écriture
-
Dessiner ce qui est transparent en utilisant une fonction de blending
Pendule-1-1-1.c
Brouillard...
-
La notion de brouillard en OpenGL correspond à une opération
selon le frame buffer et le z-buffer. Plus le pixel est loin (z-buffer),
plus sa couleur est proche de la couleur de brouillard. La couleur de brouillard
est souvent la couleur de fond. Le brouillard peut donner une bonne impression
de profondeur.
Pendule-1-1-2.c
Dessin de contours
-
Pour dessiner des contours, en mode GL_FILL, comme précédemment,
puis (l'ordre des opérations n'a pas d'importance grace au z-buffer)
on dessine les contours, en les rapprochant un peu (POLYGON_OFFSET) de
l'observateur, afin qu'ils soient visibles.
Pendule-1-1-3.c (notez
l'utilisation des listes de commandes...)
Texture
-
Le programme suivant montre comment charger une texture, et la plaquer
sur un polygone (le pendule).
Pendule-1-1-4.c , la texture
utilisée est l'image
tronquée à 128x128.
Texture et transparence
-
Il suffit de générer une textuer avec une composante alpha
et d'en tenir compte lors du blending.
Pendule-1-1-4-1.c
Définition d'une surface
Plouf-1.c
Eclairage simple
Plouf-1-1.c
Plusieurs sources de lumière... que c'est beau !
Plouf-1-1-1.c
Préparation du travail sur les reflets
-
Dans cet exemple, on fait tourner deux sinusoides autour d'une plus grosse,
et on choisit entre 3 modes : Simple, grosse sinusoide métallique,
Grosse sinusoide métalique et une petite sinusoide texturée.
Plouf-2.c
Principe du reflet métallique
-
Il faut placer une sphère au milieu de la scène, et la photographier.
-
On utilise alors la photo de cette sphère comme texture. En effet,
si on regarde un objet métallique, ce qui s'y reflete en un point
de sa surface dépend de l'angle que fait la surface en ce point
avec notre regard. Connaissant cet angle, on peut recherger le point
la photo de la sphère qui correspond au même angle sur la
sphère. La couleur de ce point est celle de la surface métallique
à l'endroit ou on regarde.
-
OpenGL sait, si on lui donne une texture correspondant à la photographie
d'une sphère argentée, déterminer en fonction du point
de vue les coordonnées de textures que doit avoir un polygone pour
simuler un reflet métallique.
-
Essayons avec une texture quelconque, juste pour voir l'effet de
ce calcul de coordonnées :
Plouf-2-1.c
-
Essayons avec un vrai reflet sphérique, même s'il ne correspond
à rien dans notre monde 3D :
Plouf-2-2.c
... Pour une surface plane, ce n'est pas terrible !!!!
-
L'idée que nous allons proposer pour calculer un vrai reflet métallique
est la suivante :
-
Comme il nous faut une image sphérique de la scène, on va
considérer qu'un' vue grand angle de la scène est une image
sphérique (il suffit de réduire la distance focale de la
caméra. En pratique, j'ai trouvé le résultat plus
joli en ne changeant carrément pas l'angle de la caméra.
Ma texture sphérique est donc une vue "normale" de la scène.
-
On prend une photo de la scène sans reflets (l'objet métallique
a une couleur de métal, dison doré).
-
On copie cette photo du frame buffer vers une zone mémoire, on la
réduit à une taille acceptable pour une texture, et on se
sert de cette réduction comme texture.
Plouf-2-1-1.c pour la sinusoide,
et Plouf-2-1-1-1.c
pour une surface plane.
Reflets dans un "vrai" mirroir
Le programme Plouf-3.c est
une mise en place du problème, il sert de base aux discussions à
venir.
Pour simuler la réflexion dans un mirroir, il faut reconstruire
la scène refletée en opérant une simétrie sur
la scène réelle. La scène refletée doit
ensuite être débarassée de tout ce qui, après
reflet, se trouverait devant la vitre du mirroit.
-
On utilise pour cela des plans de clipping Plouf-3-1.c
.
L'idée alors est de ne retenir de cette scène refletée
que ce que l'on voit à travers la vitre du mirroir. Cela revient
à ne dessiner la scène refletée que là où
elle se reflete : sur la surface de l'écran 2D occupée par
la vue en perspective du mirroir.
Reste un vrai problème de lumière, celle des reflets n'est
pas cohérente avec celle du monde réel. Je paye un café
à celle ou celui qui trouve la solution pour y remédier !
Accumulation buffer
-
Permet de faire de l'anti-aliasing
-
Permet de faire du fondu-enchainé
-
Permet de faire un effet de profondeur de champ...
GLU
Outils pour définir facilement des surfaces (avec leurs normales)
usuelles : tores, cycindres, mais aussi NURBS, etc...