Shadow mapping implementation problems

Started by
2 comments, last by Neutrinohunter 16 years, 2 months ago
I'm using the shadow mapping example from the OpenGL 2.0 Red Book. However, I am not seeing any shadowing taking place. I don't know where the problem is, I've tried everything I can think of and have followed the example closely. I have checked for both the ARB_shadow and ARB_depth_texture extensions. Here is my source:
#include <GL/GLee.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#define SM_SIZE 512

void init(void);
void display(void);
void reshape(int, int);
void idle(void);
void drawObjects(void);

GLuint shadowTex = 0;

int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
	
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(1024, 768);
	glutCreateWindow(argv[0]);
	
	init();
	
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutIdleFunc(idle);
	
	glutMainLoop();
	
	return 0;
}

void init(void)
{
	glColor3f(1, 1, 1);
	
	glClearColor(0, 0, 0, 0);
	glClearDepth(1);
	
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	
	float amb[] = {.2, .2, .2, 1};
	float white[] = {1, 1, 1, 1};
	float pos[] = {0, 5, 5, 1};
	
	glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
	glLightfv(GL_LIGHT0, GL_SPECULAR, white);
	glLightfv(GL_LIGHT0, GL_POSITION, pos);
	
	glMaterialfv(GL_FRONT, GL_AMBIENT, white);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
	glMaterialfv(GL_FRONT, GL_SPECULAR, white);
	glMaterialf(GL_FRONT, GL_SHININESS, 50);
	
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
	glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
	glLightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
	
	glGenTextures(1, &shadowTex);
	glBindTexture(GL_TEXTURE_2D, shadowTex);
	
	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, SM_SIZE, SM_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
	
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
	glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
	glEnable(GL_TEXTURE_2D);
	
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);
	glEnable(GL_TEXTURE_GEN_R);
	glEnable(GL_TEXTURE_GEN_Q);
	
	glEnable(GL_TEXTURE_2D);
	
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	
	glPolygonOffset(1, 4);
}

void display(void)
{
	double lightModelViewMatrix[16], lightProjectionMatrix[16], tmpMatrix[16];
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glPushAttrib(GL_VIEWPORT_BIT);
	glViewport(0, 0, SM_SIZE, SM_SIZE);
	
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluPerspective(45, 1, 1, 256);
	
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	gluLookAt(0, 5, 5, 0, 0, 0, 0, 1, 0);
	
	glGetDoublev(GL_PROJECTION_MATRIX, lightProjectionMatrix);
	glGetDoublev(GL_MODELVIEW_MATRIX, lightModelViewMatrix);
	
	glEnable(GL_POLYGON_OFFSET_FILL);
	drawObjects();
	glDisable(GL_POLYGON_OFFSET_FILL);
	glPopMatrix();
	
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	
	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, SM_SIZE, SM_SIZE);
	
	glPopAttrib();
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	glTranslatef(.5, .5, 0);
	glScalef(.5, .5, 1);
	glMultMatrixd(lightProjectionMatrix);
	glMultMatrixd(lightModelViewMatrix);
	glGetDoublev(GL_TRANSPOSE_MODELVIEW_MATRIX, tmpMatrix);
	glPopMatrix();

	glTexGendv(GL_S, GL_OBJECT_PLANE, &tmpMatrix[0]);
	glTexGendv(GL_T, GL_OBJECT_PLANE, &tmpMatrix[4]);
	glTexGendv(GL_R, GL_OBJECT_PLANE, &tmpMatrix[8]);
	glTexGendv(GL_Q, GL_OBJECT_PLANE, &tmpMatrix[12]);
	
	drawObjects();
	
	glutSwapBuffers();
}

void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45, (float)w/(float)h, 1, 256);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
}

void idle(void)
{
	glutPostRedisplay();
}

void drawObjects(void)
{
	static float r = 0;
	r = (r > 360) ? (0) : (r + .1);
	
	glPushMatrix();
	glRotatef(r, 0, 1, 0);
	
	glutSolidTeapot(1);
	
	glPushMatrix();
	glTranslatef(0, -1, 0);
	
	glBegin(GL_POLYGON);
	glNormal3f(0, 1, 0);
	glTexCoord2f(0, 0);		glVertex3f(-3, 0, -3);
	glTexCoord2f(1, 0);		glVertex3f(3, 0, -3);
	glTexCoord2f(1, 1);		glVertex3f(3, 0, 3);
	glTexCoord2f(0, 1);		glVertex3f(-3, 0, 3);
	glEnd();
	glPopMatrix();
	
	glPopMatrix();
}
I'm sorry I can't post anything more specific but I don't know where I'm going wrong. All help appreciated, thanks.
Advertisement
Looks like the texture generation setup is wrong.

Look at www.paulsproject.net at the SMT tutorial.

Neutrinohunter
OK, I used a cube surrounding the scene to view the results. Everything is fine except that the shadow map coords are being transformed with the objects, despite their transformations being contained by a push and pop. I don't really know why this is happening, what is the correct solution?

Thanks.

P.S.
Here are some screen shots of what I mean. When r=0 (r is scene rotation), the map is drawn correctly and I can see no unlit fragments (the light is at the camera's position now, unlike the source I posted. Only the position has been changed).
http://i95.photobucket.com/albums/l135/biggoron_2006/r0.png

However, as the scene rotates, the shadow rotates with it. The grey in the background is the unlit cube onto which the shadows are cast.
http://i95.photobucket.com/albums/l135/biggoron_2006/rg0.png

P.P.S.
Does this forum not support BBCode, or is it just offline for now?
Is that standard SM? Look good

You need to use the inverse of your rotation and multiply it in your texture generation matrix, I think it should come before your projection and modelview matrix of your light.

Since the transformation consists of only rotations, you should be save using the transpose of the scenes modelview matrix for this task.

or you could do....
void drawObjects(bool showingShadows){	static float r = 0;	r = (r > 360) ? (0) : (r + .1);		glPushMatrix();	if (!showingShadows) glRotatef(r, 0, 1, 0);		glutSolidTeapot(1);		glPushMatrix();	glTranslatef(0, -1, 0);		glBegin(GL_POLYGON);	glNormal3f(0, 1, 0);	glTexCoord2f(0, 0);		....


Neutrinohunter

This topic is closed to new replies.

Advertisement