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, &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(&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)
");
exit(-1);
}
fbo();
glutMainLoop();
}