PDA

View Full Version : glBlendFunc: Use texture as mask



Oliver Demetz
05-18-2009, 12:49 PM
Hi!

I have two textures: One is a usual RGBA semi-transparent texture showing an image which is rendered as usual.

The second texture has just one channel (float, values in inverval [0,1]). I want to implement something like a cut-tool or a "rubber"-tool. The second texture shall now act as additional alpha-mask for the first one: If the second texture is zero, also the first texture shall become invisible. And vice versa, if the second texture is one, the first shall be visible (but not ignore the alpha value of the first one).

Can I realise this using glBlendfunc?

Exemplary code:



glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, uint_image_texture);
// render the texture
// ...
glBlendFunc(???,???);
glBindTexture(GL_TEXTURE_2D, unit_masking_texture);
// overlay the cut-texture
// ...


Thanks in advance,
Olli

Ilian Dinev
05-18-2009, 01:25 PM
From what I understood, that's a task for multitexturing (easiest with GLSL), not the blend func.

zeoverlord
05-18-2009, 03:07 PM
it seems a bit complicated for the blend func, i would use a shader.

tfpsly
05-18-2009, 08:30 PM
1. That is definitely not advanced. Wrong forum.

2. Something like that should do the trick using the fixed pipeline:


glBindTexture( GL_TEXTURE_2D, texture );
glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv );

glActiveTextureARB( GL_TEXTURE1_ARB );
glClientActiveTextureARB( GL_TEXTURE1_ARB );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, textureAlphaMask );
glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv );

#if 0
// Method 1
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MO DULATE);

#else
// Or Method 2, to get more control:
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_CO MBINE_EXT);
// Color channel - Keep
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT,GL_REP LACE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_PRE VIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SR C_COLOR);
// Alpha channel - Merge
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_EXT,GL_M ODULATE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT,GL_P REVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_ SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_EXT,GL_T EXTURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_ALPHA_EXT,GL_ SRC_ALPHA);
#endif

glRenderblabla

// Cleanup
glDisable( GL_TEXTURE_2D );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glActiveTextureARB( GL_TEXTURE0_ARB );
glClientActiveTextureARB( GL_TEXTURE0_ARB );

In a pixel shader, simply do this with your two samplers:


float4 texture = tex2D(first texture blabla);
float4 textureAlphaMask = tex2D(second texture blabla);
texture.a *= textureAlphaMask.a;

Oliver Demetz
05-19-2009, 02:04 AM
Thank you for your reply.




2. Something like that should do the trick using the fixed pipeline:


glBindTexture( GL_TEXTURE_2D, texture );

// do I need this? Both my textures have same size.
glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv );

glActiveTextureARB( GL_TEXTURE1_ARB );
glClientActiveTextureARB( GL_TEXTURE1_ARB );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, textureAlphaMask );
glTexCoordPointerEXT( 2, GL_FLOAT, 0, nbvertex*2, array_uv );

#if 0
// ok, this is the way I wolud like to go:
// Method 1
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MO DULATE);
// method 2 omitted
#endif

//HERE:
// How shall I render here?
// remember: I have two textures.
glRenderblabla

// Cleanup
glDisable( GL_TEXTURE_2D );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glActiveTextureARB( GL_TEXTURE0_ARB );
glClientActiveTextureARB( GL_TEXTURE0_ARB );

By the way, do I need these *ARB* commands at all if I just use this modulate function?