I’ve got a problem with my shadow mapping, I thought I’d be able to solve it, but since all this time, I haven’t found anything wrong with them.
I was helped by paul’s project for making them (if I can remember correctly).
Here is the topic:
There’s a plane surface on which a cube is lying on it, and a light rotating around the cube. I can see well the shadow silhouette on the surface and on the cube, but the shadow doesn’t end correctly: it still continues in the direction and sense light-cube-shadow and seems not to end. I’m very embarassed with that. I can’t give any screenshots for the moment, but here is the full source code of it (note that you’ll need to load extensions if you’re not under Linux with GL 2):
#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#endif
#include <iostream>
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <cmath>
using namespace std;
GLfloat l_pos[] = {2,3,-2,1};
GLfloat l_dir[] = {0,-1,-1};
GLfloat l_dif[] = {.5,.5,.5,1.};
GLfloat white[] = {1.,1.,1.,1.};
GLfloat black[] = {0.,0.,0.,1.};
GLfloat light_projection_matrix[16];
GLfloat light_view_matrix[16];
GLfloat sm[] = {1,0,0,0};
GLfloat tmat[]={0,1,0,0};
GLfloat rm[] = {0,0,1,0};
GLfloat qm[] = {0,0,0,1};
GLfloat bias_matrix[] =
{
.5, .0, .0, .0,
.0, .5, .0, .0,
.0, .0, .5, .0,
.5, .5, .5, 1.0
};
const GLuint tex_size = 512;
GLuint shadow_map_tex;
GLubyte shadow_map_data[tex_size*tex_size];
void init()
{
glClearColor (0.,0.,0.,0.);
glShadeModel (GL_SMOOTH);
glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_LESS);
glEnable (GL_CULL_FACE);
glCullFace (GL_BACK);
glGenTextures (1, &shadow_map_tex);
glBindTexture (GL_TEXTURE_2D, shadow_map_tex);
glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, tex_size, tex_size,
0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,0);
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);
glPolygonOffset (1.1,4.);
}
void reshape (int w, int h)
{
glViewport (0,0,w,h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective (100, 4./3., .0125, 1200);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
}
void
RenderScene()
{
GLfloat tp_mat[] = {.9,.2,.1,1.};
GLfloat te_mat[] = {.0,.8,.2,1.};
GLfloat li_mat[] = {.7,.7,.0,1.};
glPushMatrix();
glTranslatef (0,1,0);
glColor3f (1,0,0);
glMaterialfv (GL_FRONT, GL_AMBIENT, tp_mat);
glMaterialfv (GL_FRONT, GL_DIFFUSE, tp_mat);
glutSolidCube (1);
glPopMatrix();
glColor3f (0,1,1);
glMaterialfv (GL_FRONT, GL_AMBIENT, te_mat);
glMaterialfv (GL_FRONT, GL_DIFFUSE, te_mat);
glBegin (GL_QUADS);
glNormal3f (0,1,0);
glVertex3f (-5,0,-5);
glNormal3f (0,1,0);
glVertex3f (-5,0,5);
glNormal3f (0,1,0);
glVertex3f (5,0,5);
glNormal3f (0,1,0);
glVertex3f (5,0,-5);
glEnd();
}
void
display()
{
static GLfloat alpha = .0;
alpha += .001;
l_pos[0] = 2 * std::cos (alpha);
l_pos[2] =-2 * std::sin (alpha);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glLoadIdentity();
gluPerspective (45., 1., 0.5, 800.);
glGetFloatv (GL_MODELVIEW_MATRIX, light_projection_matrix);
glLoadIdentity();
gluLookAt (l_pos[0],l_pos[1],l_pos[2], 0,0,0, 0,1,0);
glGetFloatv (GL_MODELVIEW_MATRIX, light_view_matrix);
glPopMatrix();
//
// First pass:
// From light's point of view
//
glCullFace (GL_FRONT);
glColorMask (GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
glMatrixMode (GL_PROJECTION);
glLoadMatrixf (light_projection_matrix);
glMatrixMode (GL_MODELVIEW);
glLoadMatrixf (light_view_matrix);
glViewport (0,0,tex_size,tex_size);
RenderScene();
glBindTexture (GL_TEXTURE_2D, shadow_map_tex);
glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, 0, 0, tex_size, tex_size);
glColorMask (GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
glCullFace (GL_BACK);
//
// Second pass:
// normal render
//
glClear (GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective (90, 4./3., 1.0, 100.);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
gluLookAt (4,4,0,0,0,0,0,1,0);
glViewport (0,0,800,600);
glLightfv (GL_LIGHT0, GL_POSITION, l_pos);
glLightfv (GL_LIGHT0, GL_AMBIENT, black);
glLightfv (GL_LIGHT0, GL_DIFFUSE, black);
glLightfv (GL_LIGHT0, GL_SPECULAR, black);
glEnable (GL_LIGHT0);
glEnable (GL_LIGHTING);
RenderScene();
//
// Third pass:
// do the shadows
//
glDepthFunc (GL_EQUAL);
glLightfv (GL_LIGHT0, GL_DIFFUSE, l_dif);
glLightfv (GL_LIGHT0, GL_SPECULAR, white);
glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv (GL_S, GL_EYE_PLANE, sm);
glEnable (GL_TEXTURE_GEN_S);
glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv (GL_T, GL_EYE_PLANE, tmat);
glEnable (GL_TEXTURE_GEN_T);
glTexGeni (GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv (GL_R, GL_EYE_PLANE, rm);
glEnable (GL_TEXTURE_GEN_R);
glTexGeni (GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv (GL_Q, GL_EYE_PLANE, qm);
glEnable (GL_TEXTURE_GEN_Q);
glBindTexture (GL_TEXTURE_2D, shadow_map_tex);
glEnable (GL_TEXTURE_2D);
glMatrixMode (GL_TEXTURE);
glLoadIdentity();
glMultMatrixf (bias_matrix);
glMultMatrixf (light_projection_matrix);
glMultMatrixf (light_view_matrix);
glMatrixMode (GL_MODELVIEW);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
glAlphaFunc (GL_GEQUAL, 0.99f);
glEnable (GL_ALPHA_TEST);
RenderScene();
glDisable (GL_ALPHA_TEST);
glDisable (GL_TEXTURE_2D);
glDisable (GL_TEXTURE_GEN_S);
glDisable (GL_TEXTURE_GEN_T);
glDisable (GL_TEXTURE_GEN_R);
glDisable (GL_TEXTURE_GEN_Q);
glDisable (GL_LIGHTING);
glDisable (GL_LIGHT0);
glDepthFunc (GL_LESS);
glPushMatrix();
glColor3f (1,1,0);
glTranslatef (l_pos[0],l_pos[1],l_pos[2]);
glEnable (GL_NORMALIZE);
glScalef (.1,.1,.1);
glutSolidSphere (1,16,16);
glDisable (GL_NORMALIZE);
glPopMatrix();
glFinish();
glGetError();
glutSwapBuffers();
glutPostRedisplay();
}
void KeyFunc (unsigned char key, int x, int y)
{
switch (key){
case 27:
exit (0);
}
}
void idle (void)
{
glutPostRedisplay();
}
int main (int argc, char**argv)
{
glutInit (&argc, argv);
glutInitWindowPosition (0,0);
glutInitWindowSize (800,600);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutCreateWindow ("Shadow mapping (testing)");
init();
glutDisplayFunc (display);
glutReshapeFunc (reshape);
glutKeyboardFunc (KeyFunc);
glutMainLoop();
return 0;
}
Thanks for any help about that problem.