Le multitexturing en OpenGL

0 Flares Twitter 0 Facebook 0 Google+ 0 Email -- Filament.io 0 Flares ×

Le multitexturing requiert le chargement d’une extension désormais intégrée dans OpenGL depuis sa version 1.3.

Pour savoir si une carte supporte une extension, reportez vous au post suivant.

La première chose à faire est d’ajouter le fichier entête suivant: glext.h, téléchargeable ici.
Ensuite, il faut déclarer les variables qui vont contenir les adreses des fonctions et qui permettront l’utilisation du multitexturing.

// spécifie si l'extension est supportée
bool multitextureSupported = false;

// spécifie le nombre d'unités de texture supportées
GLint maxTexelUnits = 1;

// les variables qui vont contenir les adresses pointant vers les fonctions utiles
PFNGLMULTITEXCOORD1FARBPROC        glMultiTexCoord1fARB    = NULL;
PFNGLMULTITEXCOORD2FARBPROC        glMultiTexCoord2fARB    = NULL;
PFNGLMULTITEXCOORD3FARBPROC        glMultiTexCoord3fARB    = NULL;
PFNGLMULTITEXCOORD4FARBPROC        glMultiTexCoord4fARB    = NULL;
PFNGLACTIVETEXTUREARBPROC        glActiveTextureARB        = NULL;

Après avoir vérifié que l’extension GL_ARB_multitexture est bien supportée, on récupère le nombre d’unités de texture supportées ainsi que les adresses pointant vers les fonctions utiles:

// nombre de textures supportées
glGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB , &maxTexelUnits );

// permet de spécifier les coordonnées d'une texture à 1 dimension (float)
glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC) wglGetProcAddress("glMultiTexCoord1fARB");

// permet de spécifier les coordonnées d'une texture à 2 dimensions (float)
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");

// permet de spécifier les coordonnées d'une texture à 3 dimensions (float)
glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC) wglGetProcAddress("glMultiTexCoord3fARB");

// permet de spécifier les coordonnées d'une texture à 4 dimensions (float)
glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC) wglGetProcAddress("glMultiTexCoord4fARB");

// permet de spécifier la texture active (sur laquelle on opère)
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");

// si tout s'est bien passé, on met notre variable à TRUE
multitextureSupported = true;

Les éléments intéressants sont chargés, place au multitexturage:
la première chose à faire est de spécifier l’unité de texture sur laquelle on souhaite travailler à l’aide de la fonction glActiveTextureARB() : la première unité se nomme GL_TEXTURE0_ARB, la seconde GL_TEXTURE1_ARB et ainsi de suite.
Ensuite, déterminez le type de texture adéquat. Par ex: glEnable(GL_TEXTURE_2D)
Spécifiez la texture que vous souhaitez utiliser avec glBindTexture().
Spécifiez éventuellement un environnement de texture avec glTexEnvf() ou glTexEnvi().
Faites d’autres opérations…
Toutes les opérations effectuées ne s’appliquent qu’à l’unité de texture spécifiée précédemment.

Pour placer votre texture, nous utiliserons une des nouvelles fonctions déclarées plus haut : glMultiTexCoord2fARB.
Elle permet de spécifier les coordonnées d’une texture à 2 dimensions, et prend trois paramètres: le premier détermine l’unité de texture sur laquelle on travaille, les 2 derniers paramètres permettent de spécifier les coordonnées de la texture de la même manière que pour appliquer une texture normale.

// UNITE DE TEXTURE #0
// on spécifie l'unité de texture sur laquelle on travaille
glActiveTextureARB(GL_TEXTURE0_ARB);

// on détermine le type de texture
glEnable(GL_TEXTURE_2D);

// on spécifie la texture à utiliser (ici tex_alpha)
glBindTexture(GL_TEXTURE_2D, tex_alpha);

// UNITE DE TEXTURE #1:
// on spécifie l'unité de texture sur laquelle on travaille
glActiveTextureARB(GL_TEXTURE1_ARB);

// on détermine le type de texture
glEnable(GL_TEXTURE_2D);

// on spécifie la texture à utiliser (ici tex_dessin)
glBindTexture(GL_TEXTURE_2D, tex_dessin);

// on spécifie comment la texture doit être interprétée lorsqu'elle est appliquée
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

// on applique notre texture sur une surface carrée
glBegin(GL_QUADS);

        // unité de texture 0
        glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f, 0.0f);
        // unité de texture 1
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f, 0.0f);
        glVertex3f(1.0f, -1.0f, 0.0f);

        glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f, 1.0f);
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f, 1.0f);
        glVertex3f(1.0f, 1.0f, 0.0f);

        glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f, 1.0f);
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f, 1.0f);
        glVertex3f(-1.0f, 1.0f, 0.0f);

        glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f, 0.0f);
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f, 0.0f);
        glVertex3f(-1.0f, -1.0f, 0.0f);

glEnd();

Dans cet exemple, la première texture (“tex_alpha”) contient une couche alpha (en plus des 3 couches RVB) mais la seconde pas.
GL_REPLACE spécifie que la seconde texture doit remplacer tous les pixels correspondants de la première texture. Comme la seconde texture ne contient pas de canal alpha, celui de la première texture est préservé.
L’image qui est résulte est une image contenant les couleurs de la seconde texture et la transparance de la première.

Pour en savoir plus sur les paramètres que la fonction glTexEnvf() peut prendre, reportez vous à cette adresse.

Si ensuite, vous désirez travaillez sur une texture “normale”, il vous faudra re-spécifier l’unité de texture sur laquelle vous souhaitez travailler (GL_TEXTURE0_ARB) et désactiver les unités de texture que vous n’utilisez pas.

// on spécifie l'unité de texture sur laquelle on travaille
// si déjà fait avant, il n'est pas nécessaire de le re-spécifier
glActiveTextureARB(GL_TEXTURE1_ARB);

// on désactive
glDisable(GL_TEXTURE_2D);

// on spécifie l'unité de texture sur laquelle on travaille
glActiveTextureARB(GL_TEXTURE0_ARB);

0 Flares Twitter 0 Facebook 0 Google+ 0 Email -- Filament.io 0 Flares ×

Leave a Comment

*