VII. Les Textures 3D▲
On se représente assez naturellement une texture 2D par un rectangle.
Une texture 3D présente une dimension supplémentaire : on peut donc se la représenter par un cube (ou un pavé).
Ces textures sont d'ailleurs également appelées Volume Texture.
De ce fait, ces textures occupent un espace mémoire relativement important.
Par exemple, une texture 3D cubique de 64 pixels de côté sans canal alpha occupe en mémoire : 64 * 64 * 64 * 3 = 786432 octets = 768 Ko.
VII-A. Utilité des textures 3D▲
Les textures 3D sont très intéressantes lorsqu'on souhaite texturer un objet sans discontinuité entre les différentes faces.
Par exemple on peut texturer notre cube pour faire croire qu'il est en bois :
Regardez bien aux arêtes du cube : il n'y a pas de discontinuité, comme si le cube était taillé dans la masse.
VII-B. Préparation de l'environnement de développement VB▲
Préparez votre application pour afficher un cube, tel qu'il est expliqué ci-dessus dans la section V : Préparation de l'environnement de développement VB.
Les textures 3D sont apparues avec la version 1.2, elles sont supportées par de nombreuses cartes graphiques (même sur portable ou ordinateur de bureautique).
Commençons tout de même par vérifier que la carte graphique les supporte, en plaçant ce code avant l'appel à InitScene :
'
Teste
si
les
textures
3D
sont
supportés,
soit
par
la
version,
soit
l'extension
EXT
If
val
(
LongToString
(
glGetString
(
GL_VERSION))) <
1
.
2
And
InStr
(
LongToString
(
glGetString
(
GL_EXTENSIONS)), "
GL_EXT_texture3D
"
) =
0
Then
MsgBox
"
Textures
3D
non
supportées
"
, vbOKOnly
Exit
Function
End
If
Bien entendu, Exit Function est à remplacer par Exit Sub si le test est codé dans la procédure Main d'une application VB6.
Les textures 3D sont supportées à partir de la version 1.2, ou dans l'extension GL_EXT_texture3D.
Si on n'est pas dans ce cas, on affiche un message et on quitte la fonction.
Importez maintenant le module ModOpenGL_1_2 qui contient les fonctions de la version 1.2.
N'oubliez pas de "mapper" ensuite les fonctions en exécutant la procédure RemapVBToGL de ce module.
'
Initialise
les
fonctions
ModOpenGL_1_2.
RemapVBToGL
Nous voici prêts à programmer les textures 3D!
VII-C. Génération de la texture▲
Déclarons tout d'abord un identifiant pour la texture, en début de module :
'
Identifiant
de
la
texture
3D
Private
gTexture As
Long
Ensuite à la fin de la fonction InitScene, on génère la texture :
'
Active
les
textures
3D
glEnable GL_TEXTURE_3D
'
Génère
un
identifiant
de
texture
glGenTextures 1
, gTexture
'
Active
cette
texture
glBindTexture GL_TEXTURE_3D, gTexture
'
Filtrage
de
la
texture
(pas
de
mipmapping
=>
linéaire)
glTexParameteri GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
glTexParameteri GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
'
Génère
les
données
de
la
texture
de
bois
Dim
lRayon As
Single
Dim
lCpt As
Long
Dim
x As
Long
, y As
Long
, z As
Long
'
Tableau
de
données
de
la
texture
Dim
ldata
(
1
To
64
&
*
64
&
*
64
&
*
3
&
) As
Byte
lCpt =
1
For
z =
1
To
64
&
For
y =
1
To
64
&
For
x =
1
To
64
&
'
Rayon
du
point
courant
lRayon =
Sqr
(
Abs
(
(
x -
32
&
) *
(
x -
32
&
) +
(
y -
32
&
) *
(
y -
32
&
)))
'
Ajoute
un
petit
décalage
en
fonction
de
la
profondeur
lRayon =
lRayon +
z /
64
'
Si
lRayon
mod
4
>
1
=>
couleur
claire,
sinon
couleur
foncée
If
(
lRayon Mod
4
>
1
) Then
'
Couleur
brun
claire
ldata
(
lCpt) =
130
'
red
ldata
(
lCpt +
1
) =
60
'
green
ldata
(
lCpt +
2
) =
10
'
blue
Else
'
Couleur
brun
foncée
ldata
(
lCpt) =
100
'
red
ldata
(
lCpt +
1
) =
45
'
green
ldata
(
lCpt +
2
) =
25
'
blue
End
If
'
Avance
de
3
byte
lCpt =
lCpt +
3
Next
Next
Next
'
Génère
la
texture
glTexImage3D GL_TEXTURE_3D, 0
, GL_RGB, 64
&
, 64
&
, 64
&
, 0
, GL_RGB, GL_UNSIGNED_BYTE, VarPtr
(
ldata
(
1
))
Le début du code est identique aux textures 2D :
0 - on active les textures avec la fonction glEnable (on active bien sûr les textures 3D).
1 - on génère un identifiant de texture avec la fonction glGenTextures.
2 - on active cette texture avec la fonction glBindTexture.
3 - on définit le filtrage de texture avec la fonction glTexParameteri; ici on applique un filtrage linéaire.
Ensuite on calcule la couleur de chaque point de la texture.
Chaque point d'un texture 2D était appelé un texel.
Pour une texture 3D, on parle de voxel.
Chaque couleur de voxel est calculée en fonction de sa position x, y et z.
On n'utilise que 3 composantes de couleur car la transparence n'est pas utile.
On génère, grâce à un test sur le rayon du point, des cercles marrons concentriques pour simuler les nervures du bois.
Pour que la texture ne soit pas trop parfaite, on ajoute un petit décalage en fonction de la profondeur z.
Finalement la texture est générée grâce à la fonction glTexImage3D :
- GL_TEXTURE_3D désigne bien évidemment une texture 3D.
- GL_RGB désigne le format des données = 3 composantes : rouge, vert et bleu.
- 64&, 64&, 64& est la taille de la texture = un cube de 64 points de côté.
- GL_UNSIGNED_BYTE désigne le type des données = Byte.
- Le dernier paramètre désigne l'emplacement des données à utiliser : c'est un pointeur (VarPtr) vers le premier élément du tableau.
VII-D. Application de la texture▲
Pour appliquer la texture au cube, il faut procéder comme pour les textures 2D.
Voici le nouveau code pour dessiner le cube texturé :
'
Affecte
la
texture
glBindTexture GL_TEXTURE_3D, gTexture
'
Début
de
la
primitive
pour
le
cube
glBegin GL_QUADS
'
Face
du
haut
Call
glTexCoord3f
(
1
, 1
, 0
): Call
glVertex3f
(
1
, 1
, -
1
)
Call
glTexCoord3f
(
0
, 1
, 0
): Call
glVertex3f
(
-
1
, 1
, -
1
)
Call
glTexCoord3f
(
0
, 1
, 1
): Call
glVertex3f
(
-
1
, 1
, 1
)
Call
glTexCoord3f
(
1
, 1
, 1
): Call
glVertex3f
(
1
, 1
, 1
)
'
Face
du
bas
Call
glTexCoord3f
(
0
, 0
, 0
): Call
glVertex3f
(
-
1
, -
1
, -
1
)
Call
glTexCoord3f
(
1
, 0
, 0
): Call
glVertex3f
(
1
, -
1
, -
1
)
Call
glTexCoord3f
(
1
, 0
, 1
): Call
glVertex3f
(
1
, -
1
, 1
)
Call
glTexCoord3f
(
0
, 0
, 1
): Call
glVertex3f
(
-
1
, -
1
, 1
)
'
Face
de
derrière
Call
glTexCoord3f
(
1
, 0
, 0
): Call
glVertex3f
(
1
, -
1
, -
1
)
Call
glTexCoord3f
(
0
, 0
, 0
): Call
glVertex3f
(
-
1
, -
1
, -
1
)
Call
glTexCoord3f
(
0
, 1
, 0
): Call
glVertex3f
(
-
1
, 1
, -
1
)
Call
glTexCoord3f
(
1
, 1
, 0
): Call
glVertex3f
(
1
, 1
, -
1
)
'
Face
de
devant
Call
glTexCoord3f
(
0
, 0
, 1
): Call
glVertex3f
(
-
1
, -
1
, 1
)
Call
glTexCoord3f
(
1
, 0
, 1
): Call
glVertex3f
(
1
, -
1
, 1
)
Call
glTexCoord3f
(
1
, 1
, 1
): Call
glVertex3f
(
1
, 1
, 1
)
Call
glTexCoord3f
(
0
, 1
, 1
): Call
glVertex3f
(
-
1
, 1
, 1
)
'
Face
de
gauche
Call
glTexCoord3f
(
0
, 1
, 1
): Call
glVertex3f
(
-
1
, 1
, 1
)
Call
glTexCoord3f
(
0
, 1
, 0
): Call
glVertex3f
(
-
1
, 1
, -
1
)
Call
glTexCoord3f
(
0
, 0
, 0
): Call
glVertex3f
(
-
1
, -
1
, -
1
)
Call
glTexCoord3f
(
0
, 0
, 1
): Call
glVertex3f
(
-
1
, -
1
, 1
)
'
Face
de
droite
Call
glTexCoord3f
(
1
, 1
, 0
): Call
glVertex3f
(
1
, 1
, -
1
)
Call
glTexCoord3f
(
1
, 1
, 1
): Call
glVertex3f
(
1
, 1
, 1
)
Call
glTexCoord3f
(
1
, 0
, 1
): Call
glVertex3f
(
1
, -
1
, 1
)
Call
glTexCoord3f
(
1
, 0
, 0
): Call
glVertex3f
(
1
, -
1
, -
1
)
glEnd
'
Désactive
la
texture
glBindTexture GL_TEXTURE_3D, 0
1 - On active d'abord les textures 3D.
2 - On active la texture à utiliser (glBindTexture).
3 - On dessine le cube en donnant des coordonnées de texture.
La principale différence par rapport à une texture 2D est que la fonction glTexCoord3f demande 3 paramètres.
Chaque vertex du cube est associé à un voxel de la texture.
Ici l'exemple est simple : on associe chaque sommet du cube à un sommet de la texture 3D.
Et enfin on désactive la texture une fois le dessin terminé.
On obtient alors le résultat attendu :