Sign in to follow this  
faculaganymede

OpenGL Shadow mapping on textured polygons

Recommended Posts

Shadow Experts, I implemented an OpenGL Performer program that makes shadows using the shadow mapping method. The program works fine if the polygons in the scene are not textured, but I don't get any shadows if the polygons are textured. Below are fragments from my source code (modified from Paul's Project). Please let me know if you find any errors. Function that initializes the shadow texture:
//Called for initiation
bool Init(void)
{
	//Shading states
	glShadeModel(GL_SMOOTH);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

	//Depth states
	glClearDepth(1.0f);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_DEPTH_TEST);

	glEnable(GL_CULL_FACE);

	//We use glScale when drawing the scene
	glEnable(GL_NORMALIZE);

	//Create the shadow map texture
	glGenTextures(1, &shadowMapTexture);
	glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
	glTexImage2D(	GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapSize, shadowMapSize, 0,
					GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	return true;
}

Here are the 3 draw passes that generate shadows:
// Draw process callback
void DrawChannel (pfChannel *chan, void *)
{
	//First pass - from light's point of view
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


	// set the modelview matrix
	glMatrixMode(GL_PROJECTION);
	glLoadMatrixd(light_proj_mat);

	// set the modelview matrix
	glMatrixMode(GL_MODELVIEW);
	glLoadMatrixd(light_view_mat);


	//Use viewport the same size as the shadow map
	glViewport(0, 0, shadowMapSize, shadowMapSize);


	//Draw back faces into the shadow map
	glPolygonOffset(2.5, 5);
	glEnable(GL_POLYGON_OFFSET_FILL);	

	//Disable color writes, and use flat shading for speed
	glShadeModel(GL_FLAT);
	glColorMask(0, 0, 0, 0);
	
	//Draw the scene
	pfDraw();

	//Read the depth buffer into the shadow map texture
	glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);

	glDisable(GL_POLYGON_OFFSET_FILL);
	glShadeModel(GL_SMOOTH);
	glColorMask(1, 1, 1, 1);	
	

//------------------------------------------------------------
	//2nd pass - Draw from camera's point of view
	glClear(GL_DEPTH_BUFFER_BIT);

	// set the modelview matrix
	glMatrixMode(GL_MODELVIEW);
	glLoadMatrixd(eye_view_mat);

	glViewport(0, 0, shadowMapSize, shadowMapSize);


	//Use dim light to represent shadowed areas
	glLightfv(GL_LIGHT1, GL_POSITION, lightPosition);
	glLightfv(GL_LIGHT1, GL_AMBIENT, black);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, black);
	glLightfv(GL_LIGHT1, GL_SPECULAR, black);

	glEnable(GL_LIGHT1);
	glEnable(GL_LIGHTING);


	pfDraw();


//------------------------------------------------------------
	//3rd pass
	//Draw with bright light
	glLightfv(GL_LIGHT1, GL_DIFFUSE, white);
	glLightfv(GL_LIGHT1, GL_SPECULAR, white);

	//Calculate texture matrix for projection
	//This matrix takes us from eye space to the light's clip space
	//It is postmultiplied by the inverse of the current view matrix when specifying texgen		
	double bias_mat[16]={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]*/

	double *tex_mat1;//=bias_mat*lightProjectionMatrix*lightViewMatrix;
	double *tex_mat;//=bias_mat*lightProjectionMatrix*lightViewMatrix;
	tex_mat1=matrixMultiplication(bias_mat, light_proj_mat);
	tex_mat=matrixMultiplication(tex_mat1, light_view_mat);


	//Set up texture coordinate generation.
	GLfloat tempS[4]={tex_mat[0], tex_mat[4], tex_mat[8], tex_mat[12]};
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGenfv(GL_S, GL_EYE_PLANE, tempS);
	glEnable(GL_TEXTURE_GEN_S);

	GLfloat tempT[4]={tex_mat[1], tex_mat[5], tex_mat[9], tex_mat[13]};
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGenfv(GL_T, GL_EYE_PLANE, tempT);
	glEnable(GL_TEXTURE_GEN_T);

	GLfloat tempR[4]={tex_mat[2], tex_mat[6], tex_mat[10], tex_mat[14]};
	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGenfv(GL_R, GL_EYE_PLANE, tempR);
	glEnable(GL_TEXTURE_GEN_R);

	GLfloat tempQ[4]={tex_mat[3], tex_mat[7], tex_mat[11], tex_mat[15]};
	glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGenfv(GL_Q, GL_EYE_PLANE, tempQ);
	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);

	//Set alpha test to discard false comparisons
	glAlphaFunc(GL_GEQUAL, 0.99f);
	glEnable(GL_ALPHA_TEST);

	pfDraw();

	//Disable textures and texgen
	glDisable(GL_TEXTURE_2D);

	glDisable(GL_TEXTURE_GEN_S);
	glDisable(GL_TEXTURE_GEN_T);
	glDisable(GL_TEXTURE_GEN_R);
	glDisable(GL_TEXTURE_GEN_Q);

	//Restore other states
	glDisable(GL_LIGHTING);
	glDisable(GL_ALPHA_TEST);

	//Restore other states
	glDisable(GL_LIGHTING);
	glDisable(GL_ALPHA_TEST);

}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I had the same problem. You'll have to use multitexturing.
What you're doing now is overwriting the shadow map with the
object's texture.
So you have to set the object's texture as the second texture
or the shadow map as the second texture and combine them properly.
I suppose you know how to do multitexturing.

Kevil

Share this post


Link to post
Share on other sites
Kevil,

Thank you for your reply.

Quote:
Original post by Anonymous Poster
I suppose you know how to do multitexturing.


Actually no, I've never done multitexturing in OpenGL or Performer. I'll need to do some reading on that. If anyone has time to explain it to me or point me to some examples, I'd appreciate that too.

Share this post


Link to post
Share on other sites
Quote:
Original post by faculaganymede
Promit,

Quote:
Original post by Promit
Why'd you make 2 posts?


Sorry if this bothered you. I'll try not to do that next time.


It's generally just not considered good form here. No worries.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this