Is this correct?

Hi people!

I’ve being longing to know if the following code will apply two textures onto one triangle in a single pass;

glBindTexture(GL_TEXTURE_2D,tex0);
glTexImage2D(GL_TEXTURE_2D, 0, compression_mode, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, rgb0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
|
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_ADD);
|
glBindTexture(GL_TEXTURE_2D,tex1);
glTexImage2D(GL_TEXTURE_2D, 0, compression_mode, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, rgb0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
glTexEnvi GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_ADD);
|
|
glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,tex0);
|
glClientActiveTextureARB(tex0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_FLOAT,0,tex0coords);
|
|
glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,tex1);
|
|
glClientActiveTextureARB(tex1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_FLOAT,0,tex1coords);
|
|
glDrawArrays(...);

Is this correct?

Would it still be single-pass if I did this for 4 textures instead of two? (assuming I have 4 texture units)

Looks ok, and yes for additional units you just have to increment the active texture between binds and it’d bind textures to the additional units.

That’s what I thought.
However, I came across the following discussion on gamedev.net:
http://www.gamedev.net/community/forums/topic.asp?topic_id=183321

Therein, people are saying it’s impossible to blend more than two textures in one pass :confused:

You did not present the whole problem as discussed there, i.e. that you required the weighted blending of 4 textures as described in that thread. The real issue is a lack of independent color registers to modulate colors with appropriate weights in the texture units IMHO. Let me go into a bit more detail.

OpenGL will automatically daisy chain the texture operations using the texenvs you have specified in order from unit zero on up. The output from one texture unit will arrive in the next as the color fragment and it will just work with the incomming texture fragment of that unit & the arithmetic as specified by the texenv & texture format.

Now, if you have a specific set of requirements like specific ways of combining textures additional issues come into play because a simple daisy chain is not very powerful and is lacking some interpolants or constants but it depends heavily on how exactly you need to ‘blend’ the textures and whether you are prepared to use combiner and crossbar extensions which significantly enhance multitexture capabilities and your ability to blend them together in interesting ways.

Just getting texture units to operate in sequence using standard texture evironments is trivial. To make things truly flexible you do need to look into the following widely supported ARB extensions:

http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_env_combine.txt

http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_env_crossbar.txt

Even given this additional functionality you may still lack some specific capability as they seem to have discovered although I’d need to do some more checking before I was sure it couldn’t be done. I hope this clarifies things for you.

P.S. I’m pretty sure it’s possible using the CONSTANT_ARB token in the combiners and specifying this color in the texenv as the GL_TEXTURE_ENV_COLOR. This isn’t of course a per vertex value but it’ll give you weights you can vary per primitive or over time.

You may also be able to store an rgb interpolant and a separate alpha interpolant in a single color (or even better) & use the combiners & crossbar to use these creatively to give per vertex weighting, but I haven’t given this much thought.

You could certainly mix & match all of the above to give you some per vertex flexibility while blending 4 weighted textures.