Multitexturing with the Alpha Channel

Started by
1 comment, last by Scavenger 19 years, 10 months ago
Hi ! I want to do multitexturing and use the alpha channel of the texture to show which parts are invisible and which should be blended with the previous texture. For example: The first texture always has ALPHA = 255 The second has some parts ALPHA = 255 (visible) and ALPHA = 0 (invisible) The third has some parts ALPHA = 0 and 0 < ALPHA < 255 (blend stuff together). At the moment this works, but if I use ALPHA = 255 and other colors than black for the second texture, the first shines through.. Here''s my init code:

glEnable (GL_Blend);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
I know that there are more operations I can use with glTexEnvi (GL_SOURCE0_...), but I''m newbie and haven''t found any good tutorial about that. Scav.
Advertisement
Do you have sample textures and sample code so we could see exactly what you are talking about. I''ve done what I ''think'' you are trying to do, but I''m not sure exactly what it is you want.
Author Freeworld3Dhttp://www.freeworld3d.org
Here's the code I use to create my displaylist:
I have no place to upload files at the moment, so I can't
show the textures. (Most textures are created at runtime anyway.)

glNewList(mt_environment.mui_displayList, GL_COMPILE);		/*			enable multitexturing or			normal texturing		*/		glEnable (GL_TEXTURE_2D);		glTexParameteri(GL_TEXTURE_2D, 				        GL_TEXTURE_WRAP_S, 						GL_REPEAT);		glTexParameteri(GL_TEXTURE_2D, 			            GL_TEXTURE_WRAP_T, 						GL_REPEAT);		glTexEnvi (GL_TEXTURE_ENV,   			       GL_TEXTURE_ENV_MODE, 			       GL_COMBINE_EXT);		glColor4f (1.0f, 					1.0f, 					1.0f,					1.0f);		switch (ui_texCount)		{			default:				/*					init multitexturing				*/				/*glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT, GL_REPLACE);				glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT, GL_TEXTURE);				glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);				glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);				glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);*/				/*					init textures				*/				glActiveTextureARB (GL_TEXTURE0_ARB);				glEnable (GL_TEXTURE_2D);				paf_mulU[0] = (*k_iter).mf_scaleX / f_envWidth;				paf_mulV[0] = (*k_iter).mf_scaleY  / f_envHeight;				(*k_iter).mpk_texture->bind ();				glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);				glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);				++k_iter;				for (UINT_8 uc_index = 1; uc_index < ui_texCount; ++uc_index, ++k_iter)				{					glActiveTextureARB (GL_TEXTURE0_ARB + uc_index);					glEnable (GL_TEXTURE_2D);					paf_mulU[uc_index] = (*k_iter).mf_scaleX / f_envWidth;				    paf_mulV[uc_index] = (*k_iter).mf_scaleY  / f_envHeight;					(*k_iter).mpk_texture->bind ();					glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);					glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_SUBTRACT);				}				break;			case 1:				paf_mulU[0] = (*k_iter).mf_scaleX / mt_environment.mk_size.get_width ();				paf_mulV[0] = (*k_iter).mf_scaleY  / mt_environment.mk_size.get_height ();				(*k_iter).mpk_texture->bind ();				glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);				break;			case 0:				glDisable (GL_TEXTURE_2D);				break;		}				glBegin(GL_TRIANGLES);			for (INT_16 i_index = 0; i_index < mt_environment.mui_triangleCount; ++i_index)			{				switch (ui_texCount)				{					default:						for (UINT_8 uc_index = 0; uc_index < ui_texCount; ++uc_index, ++k_iter)						{							glMultiTexCoord2fARB (GL_TEXTURE0_ARB + uc_index, 							                      (mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v1].mf_posX - mt_environment.mk_size.left) * paf_mulU[uc_index], 								   			      (mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v1].mf_posZ - mt_environment.mk_size.top) * paf_mulV[uc_index]);						}						break;					case 1:						glTexCoord2f((mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v1].mf_posX - mt_environment.mk_size.left) * paf_mulU[0], 	 							     (mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v1].mf_posZ - mt_environment.mk_size.top) * paf_mulV[0]);						break;					case 0:						break;				}					glVertex3f(mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v1].mf_posX,						   mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v1].mf_posY,						   mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v1].mf_posZ);				switch (ui_texCount)				{					default:						for (UINT_8 uc_index = 0; uc_index < ui_texCount; ++uc_index, ++k_iter)						{							glMultiTexCoord2fARB (GL_TEXTURE0_ARB + uc_index, 							                      (mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v2].mf_posX - mt_environment.mk_size.left) * paf_mulU[uc_index], 								   			      (mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v2].mf_posZ - mt_environment.mk_size.top) * paf_mulV[uc_index]);						}						break;					case 1:						glTexCoord2f((mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v2].mf_posX - mt_environment.mk_size.left) * paf_mulU[0], 	 							     (mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v2].mf_posZ - mt_environment.mk_size.top) * paf_mulV[0]);						break;					case 0:						break;				}					glVertex3f(mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v2].mf_posX,						   mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v2].mf_posY,						   mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v2].mf_posZ);				switch (ui_texCount)				{					default:						for (UINT_8 uc_index = 0; uc_index < ui_texCount; ++uc_index, ++k_iter)						{							glMultiTexCoord2fARB (GL_TEXTURE0_ARB + uc_index, 							                      (mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v3].mf_posX - mt_environment.mk_size.left) * paf_mulU[uc_index], 								   			      (mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v3].mf_posZ - mt_environment.mk_size.top) * paf_mulV[uc_index]);						}						break;					case 1:						glTexCoord2f((mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v3].mf_posX - mt_environment.mk_size.left) * paf_mulU[0], 	 							     (mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v3].mf_posZ - mt_environment.mk_size.top) * paf_mulV[0]);						break;					case 0:						break;				}					glVertex3f(mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v3].mf_posX,						   mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v3].mf_posY,						   mt_environment.mpak_vertexList[mt_environment.mpak_triangleList[i_index].mui_v3].mf_posZ);			}		glEnd();		/*			Disable Multitexturing again		*/		switch (ui_texCount)		{			default:				for (UINT_8 uc_index = 0; uc_index < ui_texCount; ++uc_index)				{					glActiveTextureARB (GL_TEXTURE0_ARB + uc_index);					glDisable (GL_TEXTURE_2D);				}				glActiveTextureARB (GL_TEXTURE0_ARB);				break;			case 1:			case 0:				break;		}	glEndList ();


It's not perfect code at all, but it works for my project.
But anyway.. any kind of idea to make the code less complex and/or faster is wellcome :-)

A short description of my project for better understanding:
I have to create a simulator to simulate a water surface and an oil slick on it.
The shape of the surface can change, that's why I create some
kind of triangle list. But the boundary is always a quad.

The number of textures can change as well, depending of the
things that are inserted in the scenario (Water -> 1 texture, Oil Slick -> 1 texture, Information about a current -> 1 texture, ....).

That's why everything is dynamic...

I want to have one "main" texture which represents the complete
water surface. The other textures only affect parts of the whole
surface.
An oil slick texture should overwrite parts of water texture..
A texture for a current should be combined with the water texture.
At the end I want to see water with an oil slick on it and
parts of the water coloured red to represent a current.



This are my first steps in using OpenGL so as I said before, any critic / help is welcome.

Scav.


[edited by - Scavenger on May 28, 2004 5:25:33 AM]

This topic is closed to new replies.

Advertisement