Les extensions OpenGL en VBA et VB6

Image non disponible


précédentsommairesuivant

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 = 786 432 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 :

Image non disponible

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 le support des textures 3D
Sélectionnez
' Teste si les textures 3D sont supportées, 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.

Initialisation des fonctions
Sélectionnez
' 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 :

Déclaration d'un identifiant
Sélectionnez
' Identifiant de la texture 3D
Private gTexture As Long

Ensuite à la fin de la fonction InitScene, on génère la texture :

Génération de la texture
Sélectionnez
' 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 clair
                    ldata(lCpt) = 130  'red
                    ldata(lCpt + 1) = 60  ' green
                    ldata(lCpt + 2) = 10  ' blue
                Else
                    ' Couleur brun foncé
                    ldata(lCpt) = 100  'red
                    ldata(lCpt + 1) = 45  ' green
                    ldata(lCpt + 2) = 25  ' blue
                End If
                ' Avance de 3 bytes
                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 :

  • on active les textures avec la fonction glEnable (on active bien sûr les textures 3D) ;
  • on génère un identifiant de texture avec la fonction glGenTextures ;
  • on active cette texture avec la fonction glBindTexture ;
  • et 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'une 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 trois 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 marron 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 = trois 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é :

Dessin du cube texturé
Sélectionnez
' 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 trois 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 :

Image non disponible

précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2009 Thierry GASPERMENT. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.