OpenGL Multitexturing Details w/Alpha

WakingJohn
Unregistered
 
Post: #1
Hey, Heres my set up.

I have a base texture which i put over a mesh.

I then have a list of detail textures with a list of their *seperate* GL_LUMINANCE textures to be used as alpha maps. I need to GL_COMBINE the details with the base texture while using their alpha off the luminance. I figured a good first step would be to make them at least respect their alpha and then to worry about the combining. This is what I came up with:

Code:
glActiveTextureARB( GL_TEXTURE0_ARB );//base
glEnable(GL_TEXTURE_2D);
BindTexture( base );
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_RGB_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);

glActiveTextureARB( GL_TEXTURE1_ARB );//alpha in form of luminance textures
BindTexture( detailmask  );

glActiveTextureARB( GL_TEXTURE2_ARB );//detail
BindTexture(detail );
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB, GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_TEXTURE2);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_COLOR);

All that shows up however is the base texture.
I'm really n00b so any ideas wtf is going on here would be great

=-)
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
Er, is texturing enabled on units 1 and 2?
Quote this message in a reply
WakingJohn
Unregistered
 
Post: #3
Err... it is now =-). toldja i was n00b. Thanks tons.

Instead of getting just the base texture now, its something really odd darkened tiles on the mesh. I'm going to test my texture loading again to make sure its not that.
Quote this message in a reply
WakingJohn
Unregistered
 
Post: #4
Ok, its not a loading problem and it seems to flicker a bit (darken on and off) when i zoom... ?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #5
Typically, you want to use ADD_SIGNED as the mode for the detail texture, with a 50% grey texel indicating no change. In your above setup you are instead interpolating between the base and detail texture according to the luminance of texture unit 1. Also, texture unit 1 will be modulated over the base texture before it gets to unit 2, which probably isn't what you intended.

To restate your goal-- you want to apply (not interpolate) a detail texture over the base, conditionally depending on some mixmap value? Is that right? If so, what you could do is:

unit 0: bound to base texture
unit 1: bound to mixmap
unit 2: bound to detail texture

unit 0: add_signed detail to base
unit 1: interpolate between PREVIOUS and base, depending on mixmap
unit 2: passthrough

i.e. you only need two units to do this, but you still need 3 textures
Quote this message in a reply
WakingJohn
Unregistered
 
Post: #6
Well my eventual goal is to be able to do this with up to 8 textures. But otherwise, yes.

Yet I'm not sure what you are saying. I'm still trying to come to grasps with opengl.

So unit 2 has no glTexEnvi you are saying?

I'll try to figure out exactly what you are saying. I'm still not completely understanding all this yet. *goes to fiddle with code*
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #7
For passthrough, you can use REPLACE, PREVIOUS. You'll always have to configure the texenv since the default is MODULATE.

If you intend to do this with multiple detail textures then there is a trick using DOT3 that is probably worth looking at.
Quote this message in a reply
WakingJohn
Unregistered
 
Post: #8
Hmm ok. I may do that, but first understanding this is key. =-).


This is what I think you are saying, but from results (black screen) I doubt it is.

Code:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        
//base
glActiveTextureARB( GL_TEXTURE0_ARB );
glEnable(GL_TEXTURE_2D);
BindTexture(  base );
        
//Add signed detail to base
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_RGB_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB, GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_TEXTURE2);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB,GL_SRC_COLOR);

//alpha
glActiveTextureARB( GL_TEXTURE1_ARB );
glEnable(GL_TEXTURE_2D);
BindTexture( detailmask );
                    
//interpol between base, previous, and mixmap
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB, GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB, GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_PREVIOUS );
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_COLOR);

//pass through?
glActiveTextureARB( GL_TEXTURE2_ARB );//detail    
glEnable(GL_TEXTURE_2D);                
BindTexture(detail);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_RGB_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #9
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_RGB_EXT);

^^ invalid enumerant, you mean GL_COMBINE, not GL_COMBINE_RGB. glGetError() will catch this.

Also, INTERPOLATE blends between source 0 and 1 depending on source 2, so your unit 1 setup is interpolating between base and alpha depending on "results of texture unit 0". What you want is base and previous depending on the alpha mixmap, right?

Otherwise, I think it looks OK...
Quote this message in a reply
WakingJohn
Unregistered
 
Post: #10
hmmm... still getting all black. =-/

EDIT:

OH!!!
I'm so sorry. I marked out some code with comments and accidently marked out glDrawElements ! ill post back in a sec once i do a few tweaks
Quote this message in a reply
WakingJohn
Unregistered
 
Post: #11
Ok, seems like its doing the

"Instead of getting just the base texture now, its something really odd darkened tiles on the mesh. I'm going to test my texture loading again to make sure its not that."

thing, but with it much much darker (so that it appears black at times)


Ok, swapped out something, and now its lightening instead of darkening. I had

glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_EXT, GL_REPLACE);
and now
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);


THANKS TONS for your time. I never would have gotten this far in three days of working (in fact the last three days have been mostly trying to get this to work.)
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #12
No prob. Remember to use glGetError, also search the forums for other posts with examples of working multitexture setup. Wink
Quote this message in a reply
WakingJohn
Unregistered
 
Post: #13
Aha!

Ok its almost there. I never knew glGetError() existed. I think I'm going to invest in a good opengl book sometime this week =-). These internet tutorials aren't as helpful as I'd like.

I double checked with glGetError and the guy before me did this:
Code:
glTexEnvi( GL_TEXTURE_2, GL_TEXTURE_ENV_MODE, GL_MODULATE );
So I fixed that.

Then I realized that I wasn't mapping the textures with uv! Doh! So I did this, and enabled scaling, and its now detailing correctly - which is great- except not in respect to the alpha map. hmm...

Any ideas?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #14
Post your current setup code, and a screenshot of what the problem looks like.
Quote this message in a reply
WakingJohn
Unregistered
 
Post: #15
Nevermind I figured it out. I didnt enable the texture coordinates on the alpha layer. Sorry. However, since I'm sure someone else will want this one day, here is how it works:

Code:
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

//=========================
//            Env Var and Binding
//Deal with the base
glActiveTextureARB( GL_TEXTURE0_ARB );
glEnable(GL_TEXTURE_2D);
BindTexture( base );
                
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB, GL_TEXTURE0);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_TEXTURE2);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB,GL_SRC_COLOR);

glActiveTextureARB( GL_TEXTURE1_ARB );//alpha - interpolate between PREVIOUS and base, depending on alpha
glEnable(GL_TEXTURE_2D);
BindTexture(detailmask );

glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB, GL_PREVIOUS );
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB, GL_TEXTURE0 );
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB, GL_TEXTURE1);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_COLOR);

glActiveTextureARB( GL_TEXTURE2_ARB );//detail - we pass through it
glEnable(GL_TEXTURE_2D);                
BindTexture(details );
                    
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
                                      
glMatrixMode(GL_TEXTURE);
     // Scale the detail texture to the correct size
     glLoadIdentity();
     glScalef(4.0f, 4.0f, 1);
glMatrixMode(GL_MODELVIEW);  

//=========================
//            Texture Coords & Draw
//Line those textures up
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glTexCoordPointer(2, GL_FLOAT, 0, landscape_uv);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                    
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glTexCoordPointer(2, GL_FLOAT, 0, landscape_uv);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                    
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glTexCoordPointer(2, GL_FLOAT, 0, landscape_uv);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            
//draw em        
glDrawElements( GL_TRIANGLES, 16*16*6, GL_UNSIGNED_SHORT, tri_array );

//=========================
//            Clean up!

///Clean up third
glActiveTextureARB(GL_TEXTURE2_ARB);
glDisable(GL_TEXTURE_2D);
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                    
// Turn the second multitexture pass off
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

// Turn the first multitexture pass off
glActiveTextureARB(GL_TEXTURE0_ARB);        
glDisable(GL_TEXTURE_2D);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                             
glDisable(GL_BLEND);
                    
logGlError();// my own logging function

//back to how it was when we started
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  OpenGL Alpha Channel Problem Moganza 1 2,903 Jan 19, 2013 08:25 AM
Last Post: sealfin
  OpenGL ES 2.0, 2D Alpha Transparency Artifacts Macmenace 3 7,734 Mar 28, 2010 11:18 PM
Last Post: AnotherJake
  Can't get multitexturing to work Coyote 4 3,884 Nov 16, 2009 11:48 PM
Last Post: arekkusu
  Opengl alpha premultiplication issue Najdorf 5 5,185 Nov 13, 2008 09:49 AM
Last Post: Najdorf
  Loading and using textures with alpha in OpenGL with Cocoa corporatenewt 4 5,920 Dec 8, 2007 02:06 PM
Last Post: Malarkey