XII. Les effets de lumière et de brouillard▲
XII-A. La lumière▲
XII-A-1. Les types de lumières▲
OpenGL gère 4 types de lumière :
La lumière ambiante : GL_AMBIENT.
C'est la lumière de la lampe par défaut.
Elle semble venir de toutes les directions et est réfléchie dans toutes les directions.
La lumière diffuse : GL_DIFFUSE.
Elle arrive d'une direction particulière et est réfléchie dans toutes les directions.
C'est la cas d'une lampe classique, une ampoule par exemple.
La lumière spéculaire : GL_SPECULAR.
Elle arrive d'une direction particulière et est réfléchie dans une direction particulière.
C'est la cas d'un rayon de lumière réfléchi par un mirroir par exemple.
La lumière émise : GL_EMISSION.
Elle est émise par un objet et non par une lampe.
La lumière émise n'éclaire pas les autres objets.
Les lumières peuvent se cumuler : par exemple, une lampe peut envoyer de la lumière ambiante et de la lumière diffuse en même temps.
XII-A-2. Les lampes▲
OpenGL gère 8 lampes, en plus de la lampe par défaut.
La lampe par défaut est une lumière ambiante, on le voit bien : notre cube est éclairé sur toutes ces faces comme si la lumière venait de toutes les directions.
Si on souhaite gérer notre propre lumière, il faut d'abord activer l'éclairage :
glEnable GL_LIGHTING
(ceci désactive la lampe par défaut).
Puis activer les lampes que nous souhaitons gérer :
glEnable GL_LIGHTn avec n de 0 à 7.
Les fonctions glLight* permettent de gérer les attributs des lampes :
- Le premier paramètre est le numéro de la lampe, de GL_LIGHT0 à GL_LIGHT7.
- Le second paramètre est le code de l'attribut à modifier.
- Le troisième paramètre est la valeur à affecter à l'attribut.
Les fonctions en suffixe f demandent un paramètre de type single.
Les fonctions en suffixe i demandent un paramètre de type long.
Les fonctions en suffixe fv demandent un paramètre de type tableau de single.
Les fonctions en suffixe iv demandent un paramètre de type tableau de long.
Fonction | Code de l'attribut | Valeur | Exemple |
---|---|---|---|
glLightfv ou glLightiv | GL_AMBIENT | 4 paramètres RGBA qui déterminent l'intensité et la couleur de la lumière. Si on utilise des paramètres long avec glLightiv, les valeurs sont recalculées linéairement pour que le maxi des composantes soit égal à 1. Ces paramètres peuvent être négatifs (de -1 à 1). |
Exemple de lampe bleue Sélectionnez
|
glLightfv ou glLightiv | GL_DIFFUSE | 4 paramètres RGBA qui déterminent l'intensité et la couleur de la lumière. Même utilisation que GL_AMBIENT |
|
glLightfv ou glLightiv | GL_SPECULAR | 4 paramètres RGBA qui déterminent l'intensité et la couleur de la lumière. Même utilisation que GL_AMBIENT |
|
glLightfv ou glLightiv | GL_POSITION | 4 paramètres x,y,z et w qui déterminent la position de la lampe. - Si w vaut 0, la lampe est directionnelle : x,y,z est un vecteur qui définit la direction de la lumière. - Si w vaut 1, la lampe est positionnelle : x,y,z définit la position de la source de lumière. Par défaut, la lampe est directionnelle avec un vecteur (0,0,1). |
Exemple de lampe positionnelle Sélectionnez
|
glLightf ou glLighti | GL_SPOT_CUTOFF | 1 paramètre qui définit l'angle d'émission de la lumière. La valeur est de 180° par défaut. Les valeurs possibles vont de 0 à 90; la valeur 180 est acceptée. |
|
glLightfv ou glLightiv | GL_SPOT_DIRECTION | 3 paramètres qui déterminent la direction d'un spot. La direction par défaut est (0,0,-1). Cet attribut n'est utile que si l'angle d'ouverture de la lampe (GL_SPOT_CUTOFF) n'est pas 180° (sa valeur par défaut) |
|
glLightf ou glLighti | GL_SPOT_EXPONENT | 1 paramètre qui définit l'atténuation angulaire. Valeurs de 0 à 128. L'atténuation vaut 0 par défaut et correspond à une répartition uniforme de la lumière. Plus la valeur est élevée, plus la lumière est concentrée au centre. |
|
glLightf ou glLighti | GL_CONSTANT_ATTENUATION | 1 paramètre : le coëfficient d'atténuation constant |
|
glLightf ou glLighti | GL_LINEAR_ATTENUATION | 1 paramètre : le coëfficient d'atténuation linéraire (fonction de la distance) |
|
glLightf ou glLighti | GL_QUADRATIC_ATTENUATION | 1 paramètre : le coëfficient d'atténuation quadratique (fonction de la distance au carré) |
XII-A-3. Mise en pratique▲
Nous allons ajouter une lampe diffuse qui tourne autour du cube.
Initialisons d'abord l'éclairage, dans la fonction InitScene :
'
Initialisation
de
l'éclairage
glEnable GL_LIGHTING
glEnable GL_LIGHT0
On a activé la lampe GL_LIGHT0.
Par défaut, la lampe émet une faible lumière ambiante.
On voit très légèrement le cube.
Donnons lui en plus une lumière diffuse, à la suite du code précédent :
'
Ajout
d'une
lumière
diffuse
Dim
lColor
(
1
To
4
) As
Single
lColor
(
1
) =
2
lColor
(
2
) =
2
lColor
(
3
) =
2
lColor
(
4
) =
1
glLightfv GL_LIGHT0, GL_DIFFUSE, lColor
(
1
)
La lampe émet maintenant une lumière blanche (2,2,2).
Remarquez qu'on peut utiliser des valeurs supérieures à 1.
Par défaut, elle éclaire de l'avant vers le fond.
Si vous tournez autour du cube, vous verrez que l'arrière n'est pas éclairé.
Le cube est blanc, car il est éclairé par une lumière blanche.
On a perdu les couleurs du cube.
Pour les retrouver, activer la coloration des matériaux dans l'initialisation de l'éclairage :
'
Active
la
coloration
des
matériaux
glEnable GL_COLOR_MATERIAL
On retrouve les couleurs du cube.
Pour faire tourner la lampe autour du cube on définit une variable en en-tête du module pour conserver l'angle de rotation de la lampe.
'
RotationY
de
la
lampe
Private
gLightRotate As
Double
Puis on positionne la lampe dans la fonction Render, juste après l'appel à glClear.
'
Positionne
la
lampe
gLightRotate =
gLightRotate +
0
.
03
Dim
lposition
(
1
To
4
) As
Single
lposition
(
1
) =
3
*
Cos
(
gLightRotate)
lposition
(
2
) =
0
lposition
(
3
) =
3
*
Sin
(
gLightRotate)
lposition
(
4
) =
1
glLightfv GL_LIGHT0, GL_POSITION, lposition
(
1
)
La lampe tourne mais on ne voit pas vraiment où elle se trouve et si l'éclairage est correct.
Pour matérialiser la lampe, on va dessiner une petite sphère.
Pour dessiner une sphère, on utilise la fonction gluSphere qui nous facilite la tâche.
Ajoutez le code de dessin de la sphère juste après le positionnement de la lampe :
'
Dessine
une
sphere
à
l'endroit
où
se
trouve
la
lampe
Dim
lQuad As
Long
glPushMatrix
glColor3VB vbYellow
glTranslated 3
*
Cos
(
gLightRotate), 0
, 3
*
Sin
(
gLightRotate)
lQuad =
gluNewQuadric
gluQuadricOrientation lQuad, GLU_INSIDE
gluSphere lQuad, 0
.
5
, 20
, 15
gluDeleteQuadric lQuad
glPopMatrix
Les fonctions glPushMatrix et glPopMatrix prennent ici toute leur importance.
On peut tranformer la sphère et le cube indépendamment en sauvegardant puis en restaurant la matrice de modélisation-visualisation.
Notez qu'on a défini une sphère de couleur jaune, de taille 0.5, avec 20 divisions pour les longitudes et 15 divisions pour les latitudes.
On a également modifié l'orientation de la sphère (GLU_INSIDE) de manière à ce que les faces soit éclairées (sinon une lumière à l'intérieur de la sphère ne l'éclaire pas à l'extérieur).
La sphère est créée centrée sur l'origine.
Nous la déplaçons à l'endroit où se situe la lampe avec la fonction glTranslated.
Testons notre éclairage :
On remarque un problème : la lampe est à droite et commence à éclairer la face gauche en violet.
Il se trouve qu'on a pas défini de normale lors du dessin du cube.
Il faut ajouter une normale pour chaque face du cube.
'
Début
de
la
primitive
pour
le
cube
glBegin GL_QUADS
'
Face
du
haut
=
vert
Call
glColor3d
(
0
, 1
, 0
)
Call
glNormal3d
(
0
, 1
, 0
)
Call
glVertex3d
(
1
, 1
, -
1
)
Call
glVertex3d
(
-
1
, 1
, -
1
)
Call
glVertex3d
(
-
1
, 1
, 1
)
Call
glVertex3d
(
1
, 1
, 1
)
'
Face
du
bas
=
orange
Call
glColor3d
(
1
, 0
.
5
, 0
)
Call
glNormal3d
(
0
, -
1
, 0
)
Call
glVertex3f
(
-
1
, -
1
, -
1
)
Call
glVertex3f
(
1
, -
1
, -
1
)
Call
glVertex3f
(
1
, -
1
, 1
)
Call
glVertex3f
(
-
1
, -
1
, 1
)
'
Face
de
derrière
=
rouge
Call
glColor3d
(
1
, 0
, 0
)
Call
glNormal3d
(
0
, 0
, -
1
)
Call
glVertex3f
(
1
, -
1
, -
1
)
Call
glVertex3f
(
-
1
, -
1
, -
1
)
Call
glVertex3f
(
-
1
, 1
, -
1
)
Call
glVertex3f
(
1
, 1
, -
1
)
'
Face
de
devant
=
jaune
Call
glColor3d
(
1
, 1
, 0
)
Call
glNormal3d
(
0
, 0
, 1
)
Call
glVertex3f
(
-
1
, -
1
, 1
)
Call
glVertex3f
(
1
, -
1
, 1
)
Call
glVertex3f
(
1
, 1
, 1
)
Call
glVertex3f
(
-
1
, 1
, 1
)
'
Face
de
gauche
=
violet
Call
glColor3d
(
1
, 0
, 1
)
Call
glNormal3d
(
-
1
, 0
, 0
)
Call
glVertex3f
(
-
1
, 1
, 1
)
Call
glVertex3f
(
-
1
, 1
, -
1
)
Call
glVertex3f
(
-
1
, -
1
, -
1
)
Call
glVertex3f
(
-
1
, -
1
, 1
)
'
Face
de
droite
=
bleu
Call
glColor3d
(
0
, 0
, 1
)
Call
glNormal3d
(
1
, 0
, 0
)
Call
glVertex3f
(
1
, 1
, -
1
)
Call
glVertex3f
(
1
, 1
, 1
)
Call
glVertex3f
(
1
, -
1
, 1
)
Call
glVertex3f
(
1
, -
1
, -
1
)
glEnd
Comme pour les couleurs on définit une normale par face, mais la normale s'applique à chaque vertice de la face.
Pour que l'éclairage soit correct, il faut que les normales aient une longeur de 1.
Ce qui est le cas pour nos normales lors de leur définition.
Mais lorsqu'on redimensionne la scène, où si on définit des normales plus complexes (non parallèles à un axe), elles peuvent ne plus être à la bonne taille.
Utilisez la commande glEnable GL_NORMALIZE à l'initialisation pour qu'openGL redimensionne les normales avant éclairage.
Testons à nouveau l'éclairage avec les normales :
Voilà qui est mieux, les faces sont éclairées correctement.
En y regardant de plus près, on voit que chaque face du cube est éclairée progressivement.
C'est le comportement standard, que l'on peut changer avec la fonction glShadeModel.
- glShadeModel GL_FLAT permet de colorier tout le polygone uniformément.
C'est plus rapide mais moins joli.
- glShadeModel GL_SMOOTH permet de colorier le polygone progressivement.
C'est le comportement par défaut.
XII-B. Le brouillard▲
Le brouillard est très facile à mettre en oeuvre.
Pour activer le brouillard : glEnable GL_FOG
Les fonctions glFog* permettent de gérer les attributs du brouillard :
- Le premier paramètre est le code de l'attribut à modifier.
- Le second paramètre est la valeur à affecter à l'attribut.
Les fonctions en suffixe f demandent un paramètre de type single.
Les fonctions en suffixe i demandent un paramètre de type long.
Les fonctions en suffixe fv demandent un paramètre de type tableau de single.
Les fonctions en suffixe iv demandent un paramètre de type tableau de long.
Fonction | Code de l'attribut | Valeur | Exemple |
---|---|---|---|
glFogf ou glFogi | GL_FOG_MODE | 1 paramètre qui détermine l'équation à utilisée pour gérer l'atténuation du brouillard. Les valeurs possibles sont : - GL_LINEAR pour une atténuation linéraire, c'est le plus rapide. - GL_EXP pour une atténuation exponentielle, c'est le mode par défaut. - GL_EXP2 pour une atténuation exponentielle au carré. |
Exemple d'atténuation linéraire Sélectionnez
|
glFogf ou glFogi | GL_FOG_DENSITY | 1 paramètre qui détermine la densité du brouillard. La valeur doit être positive. La densité par défaut est de 1. |
Exemple de densité de brouillard Sélectionnez
|
glFogf ou glFogi | GL_FOG_START | 1 paramètre qui détermine la distance où commence le brouillard. C'est une distance par rapport à la caméra. Valable pour un mode GL_LINEAR seulement. |
Exemple de début du brouillard Sélectionnez
|
glFogf ou glFogi | GL_FOG_END | 1 paramètre qui détermine la distance où s'arrête le brouillard. C'est une distance par rapport à la caméra. Valable pour un mode GL_LINEAR seulement. |
Exemple de fin du brouillard Sélectionnez
|
glFogf ou glFogi | GL_FOG_INDEX | 1 paramètre qui détermine l'index de la couleur du brouillard. Uniquement si la fenêtre a été créée avec des couleurs indexées (GLUT_INDEX). |
Exemple de couleur indexée du brouillard Sélectionnez
|
glFogfv ou glFogiv | GL_FOG_COLOR | 4 paramètres qui déterminent la couleur RGBA du brouillard. Uniquement si la fenêtre a été créée avec des couleurs RGB (GLUT_RGB ou GLUT_RGBA). Par défaut, le brouillard est noir (0,0,0,0). |
Exemple de brouillard gris Sélectionnez
|
glHint | GL_FOG_HINT | 1 paramètre qui détermine la qualité du brouillard. Peut valoir GL_FASTEST, GL_NICEST, ou GL_DONT_CARE. |
Exemple de brouillard moins beau mais plus rapide Sélectionnez
|
Ajoutons un brouillard gris à notre scène, dans la fonction InitScene :
'
Initialisation
du
brouillard
Dim
lfogcolor
(
1
To
4
) As
Single
glEnable GL_FOG
lfogcolor
(
1
) =
0
.
7
lfogcolor
(
2
) =
0
.
7
lfogcolor
(
3
) =
0
.
7
lfogcolor
(
4
) =
1
glFogfv GL_FOG_COLOR, lfogcolor
(
1
)
glFogi GL_FOG_MODE, GL_LINEAR
glFogf GL_FOG_START, 7
glFogf GL_FOG_END, 10
glFogf GL_FOG_DENSITY, 0
.
1
glHint GL_FOG_HINT, GL_NICEST
XIII. Rappel du code complet▲
Un rappel du contenu du module VB à ce stade du tutoriel, avec la lumière et le brouillard :
Option
Explicit
'
Temps
à
attendre
pour
le
prochaine
affichage
Private
gWaitTime As
Long
'
Temps
écoulé
pour
calcul
du
frame
rate
Private
gElapsedTime As
Long
'
Nombre
d'affichage
pour
calcul
du
frame
rate
Private
gDisplayCount As
Long
'
RotationX
Private
gRotateX As
Double
'
RotationY
Private
gRotateY As
Double
'
Zoom
Private
gZoom As
Double
'
RotationY
de
la
lampe
Private
gLightRotate As
Double
'
Fonction
principale
Function
FonctionOpenGL
(
)
'
Chargement
de
freeglut
If
LoadLibrary
(
CurrentProject.
Path
&
"
\freeglut.dll
"
) =
0
Then
MsgBox
"
Impossible
de
charger
la
librairie
freeglut
"
Exit
Function
End
If
'
Initialisation
de
la
librairie
glutInit 0
&
, "
"
'
Initialisation
du
mode
d'affichage
glutInitDisplayMode GLUT_RGBA Or
GLUT_DOUBLE Or
GLUT_DEPTH
'
Création
d'une
fenêtre
glutCreateWindow "
Tutoriel
fenêtre
GLUT
"
'
Définition
de
l'option
de
sortie
de
boucle
glutSetOption GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS
'
Fonction
d'affichage
glutDisplayFunc AddressOf CallBackDraw
'
Fonction
d'attente
glutIdleFunc AddressOf CallBackIdle
'
Fonctions
de
rappel
clavier
glutSpecialFunc AddressOf CallBackSpecial
'
Fonction
de
rappel
molette
de
souris
glutMouseWheelFunc AddressOf CallBackMouseWheel
'
Appel
de
la
fonction
d'initialisation
InitScene
'
Boucle
principale
glutMainLoop
End
Function
'
Fonction
d'affichage
Public
Sub
CallBackDraw
(
)
'
Appel
de
la
fonction
de
rendu
Call
Render
'
Echange
les
buffers
glutSwapBuffers
'
Calcul
et
affichage
du
frame
rate
gDisplayCount =
gDisplayCount +
1
If
gDisplayCount =
100
Then
glutSetWindowTitle "
Frame
rate
:
"
&
format
(
gDisplayCount /
(
glutGet
(
GLUT_ELAPSED_TIME) -
gElapsedTime) *
1000
, "
0,0
"
)
gDisplayCount =
0
gElapsedTime =
glutGet
(
GLUT_ELAPSED_TIME)
End
If
End
Sub
'
Procédure
de
rappel
attente
Public
Sub
CallBackIdle
(
)
Dim
lTimer As
Long
'
Temps
présent
lTimer =
glutGet
(
GLUT_ELAPSED_TIME)
'
Si
temps
présent
>=
au
temps
attendu
If
lTimer >=
gWaitTime Then
'
Rrafraichir
l'affichage
glutPostRedisplay
'
n
affichages
par
seconde
gWaitTime =
lTimer +
(
1000
/
50
)
End
If
End
Sub
'
Gestion
du
clavier
Public
Sub
CallBackSpecial
(
ByVal
key As
Long
, ByVal
x As
Long
, ByVal
y As
Long
)
Select
Case
key
Case
GLUT_KEY_LEFT
gRotateY =
gRotateY -
10
Case
GLUT_KEY_RIGHT
gRotateY =
gRotateY +
10
Case
GLUT_KEY_UP
gRotateX =
gRotateX -
10
Case
GLUT_KEY_DOWN
gRotateX =
gRotateX +
10
End
Select
End
Sub
'
Gestion
de
la
molette
de
la
souris
Public
Sub
CallBackMouseWheel
(
ByVal
wheel As
Long
, ByVal
direction As
Long
, ByVal
x As
Long
, ByVal
y As
Long
)
gZoom =
gZoom +
direction
End
Sub
'
Initialisation
de
la
scène
Public
Sub
InitScene
(
)
'
Initialisation
du
temps
déclencheur
de
l'affichage
gWaitTime =
glutGet
(
GLUT_ELAPSED_TIME)
'
Tests
de
profondeur
glEnable GL_DEPTH_TEST
glDepthFunc GL_LEQUAL
'
Initialisation
des
variables
de
visualisation
gRotateX =
0
gRotateY =
0
gZoom =
10
'
Initialisation
de
l'éclairage
glEnable GL_LIGHTING
glEnable GL_LIGHT0
'
Ajout
d'une
lumière
diffuse
Dim
lColor
(
1
To
4
) As
Single
lColor
(
1
) =
2
lColor
(
2
) =
2
lColor
(
3
) =
2
lColor
(
4
) =
1
glLightfv GL_LIGHT0, GL_DIFFUSE, lColor
(
1
)
'
Active
la
coloration
des
matériaux
glEnable GL_COLOR_MATERIAL
'
Initialisation
du
brouillard
Dim
lfogcolor
(
1
To
4
) As
Single
glEnable GL_FOG
lfogcolor
(
1
) =
0
.
7
lfogcolor
(
2
) =
0
.
7
lfogcolor
(
3
) =
0
.
7
lfogcolor
(
4
) =
1
glFogfv GL_FOG_COLOR, lfogcolor
(
1
)
glFogi GL_FOG_MODE, GL_LINEAR
glFogf GL_FOG_START, 7
glFogf GL_FOG_END, 10
glFogf GL_FOG_DENSITY, 0
.
1
glHint GL_FOG_HINT, GL_NICEST
End
Sub
'
Rendu
de
la
scène
Public
Sub
Render
(
)
'
Passage
en
matrice
de
projection
glMatrixMode GL_PROJECTION
'
Initialisation
de
la
matrice
glLoadIdentity
'
Définition
de
la
perspective
gluPerspective 45
, 1
, 0
.
1
, 100
'
Passage
en
matrice
de
modélisation-visualisation
glMatrixMode GL_MODELVIEW
'
Initialisation
de
la
matrice
glLoadIdentity
'
Position
de
la
caméra
gluLookAt 0
, 0
, gZoom, 0
, 0
, 0
, 0
, 1
, 0
glRotated gRotateX, 1
, 0
, 0
glRotated gRotateY, 0
, 1
, 0
'
Vide
les
buffers
couleur
et
profondeur
glClear GL_COLOR_BUFFER_BIT Or
GL_DEPTH_BUFFER_BIT
'
Positionne
la
lampe
gLightRotate =
gLightRotate +
0
.
03
Dim
lposition
(
1
To
4
) As
Single
lposition
(
1
) =
3
*
Cos
(
gLightRotate)
lposition
(
2
) =
0
lposition
(
3
) =
3
*
Sin
(
gLightRotate)
lposition
(
4
) =
1
glLightfv GL_LIGHT0, GL_POSITION, lposition
(
1
)
'
Dessine
une
sphere
à
l'endroit
où
se
trouve
la
lampe
Dim
lQuad As
Long
glPushMatrix
glColor3VB vbYellow
glTranslated 3
*
Cos
(
gLightRotate), 0
, 3
*
Sin
(
gLightRotate)
lQuad =
gluNewQuadric
gluQuadricOrientation lQuad, GLU_INSIDE
gluSphere lQuad, 0
.
5
, 20
, 15
gluDeleteQuadric lQuad
glPopMatrix
'
Sauvegarde
la
matrice
glPushMatrix
'
Rotation
du
cube
glRotated 30
, 1
, 1
, 1
'
Début
de
la
primitive
pour
le
cube
glBegin GL_QUADS
'
Face
du
haut
=
vert
Call
glColor3d
(
0
, 1
, 0
)
Call
glNormal3d
(
0
, 1
, 0
)
Call
glVertex3d
(
1
, 1
, -
1
)
Call
glVertex3d
(
-
1
, 1
, -
1
)
Call
glVertex3d
(
-
1
, 1
, 1
)
Call
glVertex3d
(
1
, 1
, 1
)
'
Face
du
bas
=
orange
Call
glColor3d
(
1
, 0
.
5
, 0
)
Call
glNormal3d
(
0
, -
1
, 0
)
Call
glVertex3f
(
-
1
, -
1
, -
1
)
Call
glVertex3f
(
1
, -
1
, -
1
)
Call
glVertex3f
(
1
, -
1
, 1
)
Call
glVertex3f
(
-
1
, -
1
, 1
)
'
Face
de
derrière
=
rouge
Call
glColor3d
(
1
, 0
, 0
)
Call
glNormal3d
(
0
, 0
, -
1
)
Call
glVertex3f
(
1
, -
1
, -
1
)
Call
glVertex3f
(
-
1
, -
1
, -
1
)
Call
glVertex3f
(
-
1
, 1
, -
1
)
Call
glVertex3f
(
1
, 1
, -
1
)
'
Face
de
devant
=
jaune
Call
glColor3d
(
1
, 1
, 0
)
Call
glNormal3d
(
0
, 0
, 1
)
Call
glVertex3f
(
-
1
, -
1
, 1
)
Call
glVertex3f
(
1
, -
1
, 1
)
Call
glVertex3f
(
1
, 1
, 1
)
Call
glVertex3f
(
-
1
, 1
, 1
)
'
Face
de
gauche
=
violet
Call
glColor3d
(
1
, 0
, 1
)
Call
glNormal3d
(
-
1
, 0
, 0
)
Call
glVertex3f
(
-
1
, 1
, 1
)
Call
glVertex3f
(
-
1
, 1
, -
1
)
Call
glVertex3f
(
-
1
, -
1
, -
1
)
Call
glVertex3f
(
-
1
, -
1
, 1
)
'
Face
de
droite
=
bleu
Call
glColor3d
(
0
, 0
, 1
)
Call
glNormal3d
(
1
, 0
, 0
)
Call
glVertex3f
(
1
, 1
, -
1
)
Call
glVertex3f
(
1
, 1
, 1
)
Call
glVertex3f
(
1
, -
1
, 1
)
Call
glVertex3f
(
1
, -
1
, -
1
)
glEnd
'
Restaure
la
matrice
glPopMatrix
End
Sub