PDA

View Full Version : Help in multitexturing



capedica
03-28-2005, 11:30 PM
Hi,
i have a little problem with multitexturing that maybe can be easy solved by an experienced people.
I'm extending a library to support shadow mapping, in this library to draw an object i simply write:


Display()
{
....
obj.Draw();
....
}In the draw method are used texture units 0 and 1 (i don't know in which way). What i'd like to do is insert my depth texture in unit 2 to realize shadowing but i've tried all kind of settings and nothing came out, i'm sure that depth texture and algorithm is correct (i've made some tests without invoking Draw method and building mesh by hand with glVertex), i think the problem is in glTexEnv settings, this is what i do (taken from Paul's tutorial):


.......
.......


static MATRIX4X4 biasMatrix(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f); //bias from [-1, 1] to [0, 1]
MATRIX4X4 textureMatrix=biasMatrix*lightProjectionMatrix;

textureMatrix= textureMatrix*lightViewMatrix;


glActiveTextureARB(GL_TEXTURE2_ARB);

//Set up texture coordinate generation.
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, textureMatrix.GetRow(0));
glEnable(GL_TEXTURE_GEN_S);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, textureMatrix.GetRow(1));
glEnable(GL_TEXTURE_GEN_T);

glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, textureMatrix.GetRow(2));
glEnable(GL_TEXTURE_GEN_R);

glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_Q, GL_EYE_PLANE, textureMatrix.GetRow(3));
glEnable(GL_TEXTURE_GEN_Q);

//Bind & enable shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glEnable(GL_TEXTURE_2D);

//Enable shadow comparison
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);

//Shadow comparison should be true (ie not in shadow) if r<=texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);

//Shadow comparison should generate an INTENSITY result
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);

// Ambient level for shadowed areas
float constColor[] = { shadowAmbient, shadowAmbient, shadowAmbient, 1.0f };
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);

// Add the ambient value to the result of the shadow test (0 or 1).
// This will then be clamped to [0, 1] so shadowed pixels will have ambient intensity,
// non-shadowed pixels will have full intensity.
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_CONSTANT_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
....Maybe the problem is in the last instructions....summaryzing: texture unit 0 and 1 are used in some way, i want put my shadow texture in unit 2 to drawing shadow, is it possible?
Thank you very much

jide
03-29-2005, 12:35 AM
At first glance I can't see bad things. But you should enable texturing and bind to your texture just after calling to glActiveTextureARB(GL_TEXTURE2_ARB). Texture functions just apply to the current bound texture.

capedica
03-29-2005, 12:51 AM
I've made it, the problems were in gTexEnvi, now with these instructions all goes right:

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);but there is another problem, now shadows are black, what if i want shadows mixed with scene?
Is there a way to realize this? (minding that texture units 0 and 1 are taken and shadow comparison is realized in the second texture unit).
Thank you

T101
03-29-2005, 01:53 AM
Modulate, AFAIK basically multiplies the two textures.
If one is 0, then the result is also 0.
If you want the shadows to be non-black, make the shadow-map a shade of gray.

capedica
03-29-2005, 03:49 AM
If you want the shadows to be non-black, make the shadow-map a shade of gray.
and how i can? the only solution that came in my mind is using arb_shadow_ambient extension but my video card (geforce4 4200Ti) doesn't support it, any ideas?

T101
03-29-2005, 04:03 AM
You seem to be using GL_MODULATE to "light" one texture by the amount specified in another texture.

Maybe I'm stupid, but who creates the texture in the first place?

Either you use some sort of render to texture functionality,
Or you render the shadow on the CPU,
Or you load a texture from disk.

Sounds to me like all of those are under your control. Why would you need an extension for that?

As an aside, there's always multi-pass and blending.

capedica
03-29-2005, 05:40 AM
Shadow texture is created by me with glCopyTexSubImage2D, i use shadow map in classic way:


//Shadow comparison should generate an INTENSITY result
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);In this way i have only white and black color that i modulate with color coming from previous texture unit but, as you said, i have only 0 or 1, so shadow is black. Instead of having 0 and 1, with shadow_ambient extension and this instruction, i have 0 or x:


glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_F AIL_VALUE_ARB,0.5);
In this way shadow is black no more...is there a way to have a similiar effect (without a third drawing pass)? and minding that i don't know what append in texture units 0 and 1, i have only output of texture unit 1. Thank you for disponibility.