PDA

View Full Version : Shadow mapping the old way



Doc
02-17-2008, 01:02 PM
So, i had some spare time so i desided i would try my hand on some simple shadow-mapping as a nice sunday afternoon project.

Anyway, thought i would try out the old GL_ARB_shadow
aproach before i would do it with GLSL, just to get the hang
of things... ofc. a big mistake as i'm now stuck on this...

My code does:
-rendering scene from eye pov... check
-copying into texture (change to fbo when rest works)... check
-sett up texture coord generation for shadow mapping... check
-sett texture matrix... check
-use shadow map to actuall show something... err...
-render scene from camera pov...check

Basically, whatever i do, i cant get the shadow map to
influence the scene when rendering from the camera pov.

Anyone got any ideas of what i did wrong/forgot?



#include <iostream>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>

#include <windows.h>
#include <GL/gl.h>

using namespace std;

float angle=0.0;
int w=800;
int h=600;

// the shadow texture
GLuint shadow_tx = 0;

//Size of shadow map
const int shadowMapSize=512;
float shadowMapNear=20;
float shadowMapFar=30.0f;
bool showDepthTexture=false;

float lightPosition[4]={20,15,0,1};
float cameraPosition[4]={0,15,15,1};
float black[4]={1,1,1,0};
float white[4]={1,1,1,0};

float lightProjectionMatrix[16];
float lightModelviewMatrix[16];

void fbo(){

//Create the shadow map texture
glGenTextures(1, &amp;shadow_tx);
glBindTexture(GL_TEXTURE_2D, shadow_tx);
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_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);
//use hardware shadow mapping
//glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE,GL_INTENSITY);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);

//Add fbo stuff and use that instead of readback into texture when everything else works
}

void drawScene(){
angle+=1;
glPushMatrix();

//glRotatef(50,1.0,0.0,0.0);
glColor3f(0,1,0);
glBegin(GL_QUADS);
glVertex3f(5,0,-5);
glVertex3f(-5,0,-5);
glVertex3f(-5,0,5);
glVertex3f(5,0,5);
glEnd();

glRotatef(angle,0.0,1.0,0.0);
glTranslatef(0,1.5,0);
glColor3f(1,0,0);
glutSolidCube(2);

glPopMatrix();
}
void changeSize(int wi, int hi){
w=wi;
h=hi;
}
void renderScene(void) {

glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//Draw from lights POV and copy into texture
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, shadowMapSize, shadowMapSize);
gluPerspective(45.0f, 1.0f, shadowMapNear, shadowMapFar);
glGetFloatv(GL_PROJECTION, lightProjectionMatrix);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( lightPosition[0], lightPosition[1], lightPosition[2],0.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, lightModelviewMatrix);

glShadeModel(GL_FLAT);
glDisable(GL_LIGHTING);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glPolygonOffset( 1.0f, 4.0f );
glEnable(GL_POLYGON_OFFSET_FILL);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, shadow_tx);
drawScene();
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT , 0, 0, shadowMapSize,shadowMapSize, 0);

///Shadow generation end. Restore normal drawing state
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glDisable(GL_POLYGON_OFFSET_FILL);





//Render from cameras POV
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45,1.0 * w/h,1,1000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(cameraPosition[0],cameraPosition[1],cameraPosition[2],
0.0,0.0,0.0,
0.0f,1.0f,0.0f);

if(showDepthTexture){
glLoadIdentity();
gluLookAt(0,0,15,
0.0,0.0,0.0,
0.0f,1.0f,0.0f);
glDisable(GL_LIGHTING);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glMultiTexCoord2f(GL_TEXTURE1, 0.0f, 0.0f);
glVertex2f(-5.0f, -5.0f);
glMultiTexCoord2f(GL_TEXTURE1, 1.0f, 0.0f);
glVertex2f(5.0f, -5.0f);
glMultiTexCoord2f(GL_TEXTURE1, 1.0f, 1.0f);
glVertex2f(5.0f, 5.0f);
glMultiTexCoord2f(GL_TEXTURE1, 0.0f, 1.0f);
glVertex2f(-5.0f, 5.0f);
glEnd();
}else{

//Some light and material parameters
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glMaterialfv(GL_FRONT, GL_SPECULAR, white);
glMaterialf(GL_FRONT, GL_SHININESS, 16.0f);

glLightfv(GL_LIGHT1, GL_POSITION, lightPosition);
glLightfv(GL_LIGHT1, GL_DIFFUSE, white);
glLightfv(GL_LIGHT1, GL_SPECULAR, white);
glLightfv(GL_LIGHT1, GL_SPECULAR, black);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);

float x[] = { 1.0f, 0.0f, 0.0f, 0.0f };
float y[] = { 0.0f, 1.0f, 0.0f, 0.0f };
float z[] = { 0.0f, 0.0f, 1.0f, 0.0f };
float w[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glTexGenfv( GL_S, GL_EYE_PLANE, x );
glTexGenfv( GL_T, GL_EYE_PLANE, y );
glTexGenfv( GL_R, GL_EYE_PLANE, z );
glTexGenfv( GL_Q, GL_EYE_PLANE, w );

glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );

glEnable( GL_TEXTURE_GEN_S );
glEnable( GL_TEXTURE_GEN_T );
glEnable( GL_TEXTURE_GEN_R );
glEnable( GL_TEXTURE_GEN_Q );

// Set up the depth texture projection
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glTranslatef( 0.5f, 0.5f, 0.5f );
glScalef( 0.5f, 0.5f, 0.5f );
glMultMatrixf(lightProjectionMatrix);
glMultMatrixf(lightModelviewMatrix);
glMatrixMode(GL_MODELVIEW);

glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, shadow_tx);

//************************************
//Here's the problem i think... what do
//i do here to actually use the r-values
//in the shadow map to draw a shadow,
//or at least dont draw to areas covered
//by shadow (3-pass approach)? Nothing
//i'v tried seems to work
//************************************

//old SGIX_shadow comparison...
//glBlendEquationEXT(GL_MIN_EXT);

//now draw the scene, hopefully at least
//see some sort of influence from the shadow map
drawScene();

//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);
}
glutSwapBuffers();
}

void main(int argc, char **argv) {
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(w,h);
glutCreateWindow("Shadow mapping test");
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(renderScene);
glewInit();

if (!glewIsSupported(
"GL_ARB_depth_texture "
"GL_ARB_shadow"
))
{
printf("Unable to load necessary extension(s)\n");
exit(-1);
}
fbo();
glutMainLoop();
}

Komat
02-17-2008, 03:07 PM
Check that the texgen generates coordinates in the space which is expected by the lightModelviewMatrix. You can also disable the comparison mode during the projection to see where the projected depth values appear.

Doc
02-17-2008, 04:52 PM
/facepalm

Thanks, you got me in the right direction...

Turned out to be just another typo when saving the lightProjectionMatrix.

when trying to do:
glGetFloatv(GL_PROJECTION_MATRIX, lightProjectionMatrix);
i guess i should NOT write:
glGetFloatv(GL_PROJECTION, lightProjectionMatrix);