Copying alpha from different texture

Greetings,

I have been struggling to understand texture combiners using GL_TEXTURE_ENV.

I read what both the Red Book and the Superbible had to say about it, but I think it just confused me even more.

I am just trying to use the alpha from one texture (maskTexture) and apply it to the alpha of another texture (imageTexture).

This is what I am trying now, seems like I must be close, but not quite there:

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D,  maskTexture);
	glEnable(GL_TEXTURE_2D);
	
	glActiveTexture(GL_TEXTURE1);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, imageTexture);
	
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
	glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA,GL_REPLACE);
	glTexEnvi(GL_TEXTURE_ENV,GL_SRC0_ALPHA,GL_PREVIOUS);
	glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA,GL_SRC_ALPHA);

Any suggestions would be greatly appreciated! I have been struggling on this for days now!

Thank you.

I’d just use a shader instead. It’s easier, cleaner and far more flexible, and will likely run faster on modern hardware too.

Yeah, I remember those. It’s like wiring up a circuit breadboard, compared to just writing the code you want in a GLSL shader. Suggest you just write a shader, but if you have a good reason …

I am just trying to use the alpha from one texture (maskTexture) and apply it to the alpha of another texture (imageTexture). This is what I am trying now, seems like I must be close, but not quite there:

You haven’t set up your texturing functions for both texture units, and you haven’t designated what should happen for RGB. It’s also not clear what you mean by “apply”. Modulate?

Have a look here for a few examples, specifically the one I’m pointing you to:

http://www.opengl.org/wiki/Texture_Combiners#Example_:_Blend_tex0_and_tex1_based_on_alpha_of_tex0

Note that for each stage, you set up an texturing function for RGB, and an operation for ALPHA. For each, you have 3 inputs (sources) that you can pull from various places. For each of these you have an operation (operand) that can perform some “munge” of the value before you actually feed these inputs into the texturing function (GL_COMBINE_RGB or GL_COMBINE_ALPHA). The texturing function has a predefined “mixing” effect on the various inputs. E.g. GL_REPLACE just uses input 0 (after operand munge). GL_MODULATE just multiplies inputs 0 and 1 (again after operand munges). GL_INTERPOLATE is one of the few that uses input 2.

I agree, given the way things are named it’s not too obvious on the face of it what’s going on, but after you see the pattern, it’s like pulling teeth. Not too bad :wink:

Thanks for the replies.

I have to support OpenGL ES 1.1, so shaders are not an option.

I have tried the examples that you refer to, but that one blends the RGB based on the alpha. The problem is there are an ifinite number of combinations, and I have already spent days trying everything I can think of.

I do not want to affect the RGB at all, just apply the alpha from one texture (that is a FBO) to another texture.

My goal was to show you the pattern so you could solve your own problem, not to solve it for you.

I do not want to affect the RGB at all, just apply the alpha from one texture (that is a FBO) to another texture.

That’s pretty simple. Given what I mentioned, you should be able to knock this out. Texture unit 0: replace (rgb and alpha) from texture. Texture unit 1, RGB replace with previous, alpha replace with texture alpha.

Take this with a bag of salt as I haven’t written texture combiners in 8 years, but…


// Texture unit 0: Pull in RGB and ALPHA from TEXTURE0 as new fragment color
glActiveTexture( GL_TEXTURE0 );
glBindTexture  ( GL_TEXTURE_2D, tex0 );
glTexEnvi      ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//------------------------
// Texture unit 1: Copy fragment RGB across.  But pull ALPHA from TEXTURE1
glActiveTexture( GL_TEXTURE1 );
glBindTexture  ( GL_TEXTURE_2D, tex1 );
glTexEnvi      ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
glTexEnvi      ( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE );
glTexEnvi      ( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS );
glTexEnvi      ( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
//------------------------
glTexEnvi      ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE );
glTexEnvi      ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE );
glTexEnvi      ( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );

Thanks Dark Photon, I appreciate your help!

The problem I am having is that I cannot find any examples of what I am trying to do, and I really learn best by doing.

After days of trying everything I can think of, I am really interested in seeing how it works.

Thanks for your example, but I just see the original RGB without any alpha from tex1.

So I just realized that I have to have blending enabled (duh!).

With your example, the alpha channel is brightening (adding?) to the RGB.

I am struggling to understand but I am still really confused on what the different enums do and why they are used the way they are.

I’d modify the final part to this:


glTexEnvi      ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE );
glTexEnvi      ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS );
glTexEnvi      ( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE );
glTexEnvi      ( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
glTexEnvi      ( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA );

Thanks for your help everyone. I really appreciate it!

Your suggestions were close, but not quite right. I just got it working from a web page that I found with very detailed explanation at: GameDev.net.

Here is the solution:

//1) Select the stage
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, _textures[kTextureTest1] );
//2) Setup to use the ARB_texture_env_combine settings
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
//3) Setup the sources. Since this is just "default" settings, sources are simply the current texture
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
//4) Setup how the incoming (source) RGB data affects the output. Since it is the base texture, a simple replace should do.
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
	
//1) Select the stage
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, _textures[kTextureTestAlpha] );
//2) Setup the sources for color data. The sole source is the incoming color from stage0
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
//3) Setup the sources for alpha data. This is drawn from the current alpha-map texture.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
//4) Setup the equation to combine the source color to generate output color data. This is simple replace, since we want the color data as output by stage0 to be used as-is.
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
//5) Setup the equation to combine the source alphas. This is, again, a simple replace, to replace source0 (texture) alpha.
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);

Thanks again!