Cette opération consiste à appliquer plusieurs textures en même temps sur des triangles.
L'inconvénient d'afficher plusieurs textures en plusieurs passes est que vous allez envoyer plusieurs fois les même triangles à la carte, qui va devoir les transformer à nouveau. Le multitexturing évite cela, en appliquant les textures en même temps, ce qui est évidemment plus rapide.
glBindTexture( GL_TEXTURE_2D, texture0 ); glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv0 ); glDrawElements( GL_TRIANGLES, nbaff*3,GL_TYPE_INDEXE_ARRAY,indexes ); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv1 ); glBindTexture( GL_TEXTURE_2D, texture1 ); glDrawElements( GL_TRIANGLES, nbaff*3,GL_UNSIGNED_SHORT,indexes ); glDisable(GL_BLEND);
//Texture 1 dans la Texture Unit 0 glBindTexture( GL_TEXTURE_2D, texture1 ); glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv1 ); //Active la Texture Unit 1, active le placage de texture pour cette TU glActiveTextureARB( GL_TEXTURE1_ARB ); glClientActiveTextureARB( GL_TEXTURE1_ARB ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glEnable( GL_TEXTURE_2D ); //Configure le blending des 2 textures glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_EXT); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT,GL_INTERPOLATE_EXT); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_PREVIOUS_EXT); glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT,GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_EXT,GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_EXT,GL_SRC_ALPHA); //Texture 0 dans TU 1 glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv0 ); glBindTexture( GL_TEXTURE_2D, texture0 ); //Affichage glDrawElements( GL_TRIANGLES, nbaff*3,GL_TYPE_INDEXE_ARRAY,indexes ); //Désactive la TU 1 glDisable( GL_TEXTURE_2D ); glDisableClientState( GL_TEXTURE_COORD_ARRAY ); glActiveTextureARB( GL_TEXTURE0_ARB ); glClientActiveTextureARB( GL_TEXTURE0_ARB );
Comme vous le voyez, le blending par glBlendFunc disparaît. En effet glBlendFunc mélange le pixel final (après toutes les TU) avec l'image déjà affichée, et non pas le pixel de la TU courante avec celui de la TU précédente.
Cette image décrit la chaîne de processus appliquée à vos texels :
Il y a quatre méthode de blending:
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE):
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_ADD):
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE):
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_EXT):
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT, x )
Operation | Résultat |
GL_REPLACE | Source0 |
GL_ADD | Source0 + Source1 |
GL_ADD_SIGNED_EXT | Source0 + Source1 - 0.5 |
GL_MODULATE | Source0 * Source1 |
GL_INTERPOLATE | Source0*Source2 + Source1*(1-Source2) |
GL_DOT3_RGB_EXT | Somme sur R,G,B de (Source0-0.5)*(Source1-0.5) |
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT, x )
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT, x )
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT, x )
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT, x )
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_EXT, x )
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_EXT, x )Idem pour la source2. Celle-ci n'est utilisée que si on est en mode GL_INTERPOLATE.
(Source0/Operand0)*(Source2/Operand2) + (Source1/Operand1)*(1-Source2/Operand2)
A noter que pour la TU0, le "résultat précédent" (source0=GL_PREVIOUS_EXT) est la valeur donnée par glColor (après éclairage si activé).
Pour savoir combien de Texture Units sont disponibles:
int nb_multitexture = 0; glGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB,&nb_multitexture );
Avec le multitexturing, vous ne pouvez blender avec l'écran que le résultat de la dernière TU, l'opération glBlendFunc n'ayant lieu qu'après application de toutes les textures.
Good luck!
Main page | email : Sly |