Rendering with multitexture: one texture on top of the previous texture? how

Started by
17 comments, last by Emark 14 years, 4 months ago
I have two RGBA images that i want to combine as one image, they can have transparency and that transparency should be combined as well, example: Blue color means 100% transparent pixels. I found some multitexture examples for something similar, but i wasnt able to modify it to my purposes, could someone give good guide for these glTexEnvf() parameters, because they makes no sense to me :E it should be simple but this code below is nothing like simple... Or give me the correct parameters to these functions to do the trick, if you feel like that :P

	glEnable(GL_BLEND);

	glActiveTextureARB(GL_TEXTURE0_ARB );
	glEnable( GL_TEXTURE_2D );
	glBindTexture( GL_TEXTURE_2D, g_textureID_0 );
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
	glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_COMBINE_ARB);
	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE1);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE1);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);

	glActiveTextureARB( GL_TEXTURE1_ARB );
	glEnable( GL_TEXTURE_2D );
	glBindTexture( GL_TEXTURE_2D, g_textureID_1 );
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
	glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_COMBINE_ARB);
	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE1);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE1);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
	

	
	glColor4f(1, 1, 1, 1);
 
	glBegin( GL_QUADS );
		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 0.0f );
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 0.0f );
		glVertex3f( -1.0f, -1.0f, 0.0f );

		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 1.0f );
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 1.0f );
		glVertex3f( -1.0f, 1.0f, 0.0f );

		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1.0f, 1.0f );
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1.0f, 1.0f );
		glVertex3f( 1.0f,  1.0f, 0.0f );

		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1.0f, 0.0f );
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1.0f, 0.0f );
		glVertex3f( 1.0f, -1.0f, 0.0f );
	glEnd();

	glActiveTextureARB(GL_TEXTURE0_ARB);
	glDisable(GL_TEXTURE_2D);
	glActiveTextureARB(GL_TEXTURE1_ARB);
	glDisable(GL_TEXTURE_2D);

Any help appreciated.
Advertisement
You have to add "glBlendfunc GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA" before the "glBindTexture"
edit:
But i am not shure...

[Edited by - verty on December 4, 2009 3:32:31 PM]
oh yeah i forgot to include that to this code on this page, but i have that setting in my original code already.
I guess what you want is the GL_INTERPOLATE_ARB state
Example is here
http://www.opengl.org/wiki/Texture_Combiners#Example_:_Blend_tex0_and_tex1_based_on_alpha_of_tex0
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
I tested that code, but it doesnt work... the wall texture works, but i only see white in the transparent areas, the pipe texture isnt there at all, code:

void render(){	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );	glMatrixMode( GL_MODELVIEW );	glLoadIdentity();	glTranslatef( 0.0f, 0.0f, g_fDistance );	glRotatef( -g_fSpinY, 1.0f, 0.0f, 0.0f );	glRotatef( -g_fSpinX, 0.0f, 1.0f, 0.0f );	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);	glEnable(GL_BLEND);	glActiveTextureARB(GL_TEXTURE0);	glEnable(GL_TEXTURE_2D);	glBindTexture(GL_TEXTURE_2D, g_textureID_0);	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);	//------------------------	glActiveTextureARB(GL_TEXTURE1);	glEnable(GL_TEXTURE_2D);	glBindTexture(GL_TEXTURE_2D, g_textureID_1);	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);   //Interpolate RGB with RGB	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);	//------------------------	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);   //Interpolate ALPHA with ALPHA	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);	glColor4f(1, 1, 1, 1);	glBegin(GL_QUADS);		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 0.0f );		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 0.0f );		glVertex3f( -1.0f, -1.0f, 0.0f );		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 1.0f );		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 1.0f );		glVertex3f( -1.0f, 1.0f, 0.0f );		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1.0f, 1.0f );		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1.0f, 1.0f );		glVertex3f( 1.0f,  1.0f, 0.0f );		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1.0f, 0.0f );		glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1.0f, 0.0f );		glVertex3f( 1.0f, -1.0f, 0.0f );	glEnd();	glActiveTextureARB(GL_TEXTURE0_ARB);	glDisable(GL_TEXTURE_2D);	glActiveTextureARB(GL_TEXTURE1_ARB);	glDisable(GL_TEXTURE_2D);	SwapBuffers( g_hDC );}


any ideas?

i know for sure that textures are loaded properly, i tested without multitexturing and the alpha is there etc.

Edit: if i put color to glColor4f(1, 1, 1, 0.5f); then i can see the pipe texture 50% and wall 50% ... doesnt make any sense. how i can make both textures show there with full opacity, just like the example image i made?

if i switch g_textureID_1 and g_textureID_0, then i see pipe texture but not wall texture at all.
Edit: This is the best result so far i got, but its still a bit wrong:

As you see the transparent edges are copied from the underlying image on the top image, so it makes holes there.

How to fix this to match the first post example result?

My current code:
	glActiveTextureARB(GL_TEXTURE0);	glEnable(GL_TEXTURE_2D);	glBindTexture(GL_TEXTURE_2D, g_textureID_1);	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);	//------------------------	glActiveTextureARB(GL_TEXTURE1);	glEnable(GL_TEXTURE_2D);	glBindTexture(GL_TEXTURE_2D, g_textureID_0);	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);	//------------------------	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);   //Interpolate RGB with RGB	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);	//------------------------	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);   //Interpolate ALPHA with ALPHA	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_TEXTURE);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);


[Edited by - Emark on December 5, 2009 9:30:59 AM]
That depends on the alpha values that you have in g_textureID_1. Be sure that you understand what that glTexEnv code does. Don't just copy and paste.

You also have called glEnable(GL_BLEND). Are you sure you want blending on?
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
yes i want to see through the texture areas that are transparent.

"Be sure that you understand what that glTexEnv code does"

can you offer some good guide for these things?
Great, i finally made it work after long trial & error ^^

GL_ADD was the keyword.

Current code:
	glActiveTextureARB(GL_TEXTURE0);	glEnable(GL_TEXTURE_2D);	glBindTexture(GL_TEXTURE_2D, g_textureID_0);	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);	//------------------------	glActiveTextureARB(GL_TEXTURE1);	glEnable(GL_TEXTURE_2D);	glBindTexture(GL_TEXTURE_2D, g_textureID_1);	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);	//------------------------	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);   //Interpolate RGB with RGB	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);	//------------------------	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);   //Interpolate ALPHA with ALPHA	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_TEXTURE);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);


Another question: How i can make this whole quad 50% transparent now? if i add: glColor4f(1, 1, 1, 0.5f); then only the other texture is transparent :/ i cant make it all transparent, as it was just one image. Help?
You would need another texture unit.

glActiveTexture(GL_TEXTURE2);
glBindTexture(...you have to bind some dummy texture here so that the unit is considered valid...);

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_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);

so that takes result of previous stage RGB and it just outputs.
It takes alpha of previous stage and multiplies by alpha of you set with

float mycolor[4];
mycolor[0]=mycolor[1]=mycolor[2]=0.0; //RGB doesn't matter since we are not using it
mycolor[3]=0.75; //Set the blend factor with this
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, mycolor);

PS : you should get rid of this 10 year old stuff and start using shaders. That is why that page shows GLSL code examples in parallel
http://www.opengl.org/wiki/Texture_Combiners
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

This topic is closed to new replies.

Advertisement