Multitexturing with OpenGL

Introduction, a short exemple

Multitexturing means that you are displaying several textures at the same time on triangles.
The drawback of having to display several textures on the same triangle(s) using many passes is that the graphic card will transform many time the same triangles and vertices, whereas it can transform them only once and apply many texture on it at the same time using multitexturing, which is obviously faster.

Old code style:

glBindTexture( GL_TEXTURE_2D, texture0 );
glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv0 );
glDrawElements( GL_TRIANGLES, nbaff*3,GL_UNSIGNED_SHORT,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_TYPE_INDEXE_ARRAY,indexes );

glDisable(GL_BLEND);

Multitexturing code:


//Texture 1 on the Texture Unit 0
glBindTexture( GL_TEXTURE_2D, texture1 );
glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv1 );

//Switch on the Texture Unit 1, switch on texture mapping on this TU
glActiveTextureARB( GL_TEXTURE1_ARB );
glClientActiveTextureARB( GL_TEXTURE1_ARB );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glEnable( GL_TEXTURE_2D );

//Set up the blending of the 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 on TU 1
glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv0 );
glBindTexture( GL_TEXTURE_2D, texture0 );

//Rendering
glDrawElements( GL_TRIANGLES, nbaff*3,GL_TYPE_INDEXE_ARRAY,indexes );

//Switch off the TU 1
glDisable( GL_TEXTURE_2D );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glActiveTextureARB( GL_TEXTURE0_ARB );
glClientActiveTextureARB( GL_TEXTURE0_ARB );

Explications

Vocabulary : TU = Texture Unit

As you can see, the blending using glBlendFunc disappear. Indeed, glBlendFunc blend the final computed pixel (after every TUs) with the screen pixel, whereas we want here to mix the pixels from both textures.

The following picture describes the whole process applied to your texels:

Multitexturing

There are four blending methods:

Note that in the TU0, "previous result" (source0=GL_PREVIOUS_EXT) means the color given by glColor, after lighting if enabled.

In order to know how many Texture Units are available:

int nb_multitexture = 0;
glGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB,&nb_multitexture );

Something you cannot do (yet) with multitexturing : you cannot blend any TU but the last one with the screen, as the glBlendFunc operation is done after all the texturing application have been computed.

Good luck!


Main page

email : Sly