GL_ARB_MULTITEXTURE & alpha blending, is it possible?

I’ve converting my two-pass rendering code to using multitextures but I’m stumped at how to convert:

glDisable(GL_BLEND);
glBindTexture();
Draw_Object();
glEnable(GL_BLEND);
glBindTexture();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.f, 1.f, 1.f, 0.5);
Draw_Object();

to using multitexturing. It seems defining two texture units, it seems the following doesn’t
do the trick:

glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable (GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBindTexture();
Draw_Object();

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBindTexture();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Draw_Object();

Any suggestions?

e

With multitexturing there are more than one textures applied in one step. No need to draw the object twice.

Have a look at “Simple Multitexturing in OpenGL” here: http://www.nvidia.com/marketing/developer/devrel.nsf/TechnicalDemosFrame?OpenPage

Sorry, the source snippet is wrong, you can assume I am only drawing the object once.

The problem is how do I alpha blend the second texture unit based on the source and alpha color on the first texture unit.

I suspect I need to use GL_COMBINE_EXT.

e

Nope, GL_EXT_texture_env_combine is not flexible enough to do that. It only does combinations of the form Arg0Arg1+Arg2. You need Arg0Arg1+Arg2*Arg3. NVIDIA cards starting with the TNT and moving forward, support an extension to do those types of combinations, GL_NV_texture_env_combine4. I’m sure some other video cards must have something similiar.

Yes, I think it is flexible enough. He wants to do Tex0srcAlpha + Tex1(1-srcAlpha). GL_EXT_texture_env_combine defines a GL_INTERPOLATE_EXT mode that performs
Arg0 * (Arg2) + Arg1 * (1-Arg2)

This is from the nVidia extension documentation. Try looking here:
http://www.nvidia.com/Marketing/Develope…OpenGLspecs.pdf

start looking at page 129 of the document.

Yep your right, I totally forgot about that interpolate mode. Thanks.

Maybe I’m wrong ,but the arg2 argument is restricted only to the alpha component of the corresponding source. The source above doesn’t say anything about the TexEnvf of the first pass, but I think that the first rendering pass draw the object normally (modulated or decal) and the second pass use the alpha component of the first texture as a mask to draw the second texture.
If that’s the case then you want PRIMARY_COLOR *Tex0_RGB + Tex1_ RGB *(1-srcAlpha).
This is something you can’t do with GL_EXT_texture_env_combine with one pass,but only with GL_NV_texture_env_combine4 or the register combiners.

[This message has been edited by pavlos (edited 09-25-2000).]

I guess we need ericb to clarify what he meant, but his original multi-pass source code was:

glDisable(GL_BLEND);
glBindTexture();
Draw_Object();
glEnable(GL_BLEND);
glBindTexture();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.f, 1.f, 1.f, 0.5);
Draw_Object();

It appears to me that he isnt specifying any color component in the first pass before calling Draw_Object(). And I can argue that he must not be setting the color inside Draw_Object, because then that would override his call to glColor4f in the second pass. Therefore, I conclude that in his scenario, pass 1 is a replace with blend and pass 2 is a modulate with an alpha blend. This can be done with GL_EXT_texture_env_combine in one pass. If he intended something else, then the code wasnt clear enough to me.

You’re correct.

Actually, I am setting the color in Draw_Object(), I just places glColor4f outside for illustration purposes – the alpha color in the first pass is ignored, so I left out glColor. You could assume it is the same:

glColor(1.f, 1.f, 1.f, 0.5);

Could you give me some pseudo-code for GL_EXT_texture_env_combine?

Also any good examples out there or theory on texture_env_combine?

Thanks for the responses.

Ok, after tinker with GL_COMBINE_EXT I figured it out a quick-and-dirty fix. Althrough the alpha values are flipped, I could solve this with glColor(1.f, 1.f, 1.f, 1-a);

Here it is:

for TEXTUREUNIT0, use:
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture();
glTexEnvi(GL_TEXTURE_ENV,
GL_TEXTURE_ENV_MODE, GL_REPLACE);

nothing special, but for TEXTUREUNIT1, use:

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture();

glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_EXT);

glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT);

Like I said, it works fine except the alpha values are inverted.

Any suggestions on how to improve it?

Thanks,
e