Hello all!
I’m working on a project about Ray Tracing with the help of OpenGL. My current task is to enhance a simple Ray Caster with Shadow Mapping… And there I have a problem: I want to render the scene from the light’s point of view and then read back the Z Buffer to get the light’s depth map…
Here is my code:
// Shadow Mapping structure
typedef struct _ShadowMap {
double MVPMatrix[16]; // light’s model view projection matrix
double modelviewMatrix[16]; // light’s model view matrix
double projectionMatrix[16];// light’s model view projection matrix
float left; // Frustum borders
float right; // Frustum borders
float bottom; // Frustum borders
float top; // Frustum borders
float near; // Frustum borders
float far; // Frustum borders
float *shadowMap; // Shadow Map
int size; // Map size
} ShadowMap;
//------------------------------------------------------------------------------
// Initializes the shadow map structure
//------------------------------------------------------------------------------
ShadowMap *createShadowMap(Shared *data, int size)
{
GLuint shadowMapFBODepth;
GLuint shadowMapFBOColour;
ShadowMap result = (ShadowMap)malloc(sizeof(ShadowMap));
result->size = size;
result->shadowMap = (float*)malloc(size * size * sizeof(float));
result->left = -5;
result->right = 5;
result->bottom = -5;
result->top = 5;
result->near = 0;
result->far = 5;
//model view
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
gluLookAt(2*data->lights[0].position[0],
2*data->lights[0].position[1],
2*data->lights[0].position[2],
0., 0., 0.,
0., 1., 0.);
glGetDoublev(GL_MODELVIEW_MATRIX, result->modelviewMatrix);
glPopMatrix();
//projection
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(result->left, result->right,
result->bottom, result->top,
result->near, result->far);
glGetDoublev(GL_PROJECTION_MATRIX, result->projectionMatrix);
float scaleBias[16] = {0.5, 0, 0, 0,
0, 0.5, 0, 0,
0, 0, 0.5, 0,
0.5, 0.5, 0.5, 1 };
//MVP matrix = S * P * MV
glLoadIdentity();
glLoadMatrixf(scaleBias);
glMultMatrixd(result->projectionMatrix);
glMultMatrixd(result->modelviewMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, result->MVPMatrix);
glPopMatrix();
return result;
}
//------------------------------------------------------------------------------
// Updates the shadow map
//------------------------------------------------------------------------------
void updateShadowMap(Shared *data, ShadowMap *shadowMap)
{
//Look from light
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glLoadMatrixd(shadowMap->modelviewMatrix);
//orthographic projection
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glLoadMatrixd(shadowMap->projectionMatrix);
glViewport(0, 0, shadowMap->size, shadowMap->size);
//render depth values
glClearDepth(1.0f);
glEnable( GL_DEPTH_TEST);
glClear( GL_DEPTH_BUFFER_BIT );
int i;
float *face;
glBegin( GL_TRIANGLES );
for( i=0; i<data->model->numFaces; i++ )
{
face = data->model->faces[i].a;
glVertex3f( face[0], face[1], face[2] );
face = data->model->faces[i].b;
glVertex3f( face[0], face[1], face[2] );
face = data->model->faces[i].c;
glVertex3f( face[0], face[1], face[2] );
}
glEnd();
glReadPixels(0, 0, shadowMap->size, shadowMap->size, GL_DEPTH_COMPONENT, GL_FLOAT, shadowMap->shadowMap);
#if 1 // Set to 1 to output the shadow map as RAW image file
FILE *shadowMapDump;
shadowMapDump = fopen(“shadowMap.raw”, “wb”);
fwrite(shadowMap->shadowMap, sizeof(ubyte), shadowMap->size * shadowMap->size, shadowMapDump);
fclose(shadowMapDump);
#endif
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glViewport(0, 0, data->winWidth, data->winHeight);
CheckErrorsGL("updateShadowMap");
}
When running this, I get an OpenGL error: ‘1468 [Error]: OpenGL error ‘invalid operation’ (updateShadowMap)’. Apparently, the readback of the shadow map fails…
Can anyone point me in the right direction how to read back the contents of the depth buffer?