i am working on a OpenGL project and have problems with my shadows. They are not displayed and i dont know why. The code, which i use, is from http://www.paulsproj...ls/smt/smt.html .
The idea is:
I draw the scene three times. In the first draw, i write the depth values in a FBO from the lightview direction.
In the second draw, i draw the scene normal with (0.2, 0.2, 0.2, 1) light intensity.
In the third step i draw the scene with bright light and make a comparison with the depth values. Here is the code: The first part is my shadow class and the second part my viewer class. In the viewer class all draws etc. are handled.
void Shadows::generateShadowBuffer()
{
shadowMapSize = 512;
// Init texture
glGenTextures(1, &_depthTextureId);
glBindTexture(GL_TEXTURE_2D, _depthTextureId);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, shadowMapSize, shadowMapSize,
0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
// Init buffer
glGenFramebuffersEXT(1, &_fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fboId);
// attach the texture to FBO color attachment point
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_TEXTURE_2D, _depthTextureId, 0);
// Instruct openGL that we won't bind a color texture with the currently binded FBO
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
// check FBO status
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
printf("Buffer init wasnt correct.\n");
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
// Check for Error
GLenum error = glGetError();
if(error != 0)
{
printf("Error occured in Shadows::generateShadowBuffer: %d\n", error);
if(GL_STACK_OVERFLOW == error)
printf("GL_STACK_OVERFLOW\n");
if(GL_STACK_UNDERFLOW == error)
printf("GL_STACK_UNDERFLOW\n");
}
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void Shadows::drawFromLight(Vector lightPosition)
{
// Activate Buffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fboId);
// clear buffers
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(0, 0, 0, 0);
// Init matrices
glPushMatrix();
glLoadIdentity();
gluPerspective(60.0f, 1.0f, 0.1f, lightPosition.y + 10);
glGetFloatv(GL_MODELVIEW_MATRIX, _projectionMatrix);
glPopMatrix();
glPushMatrix();
glLoadIdentity();
gluLookAt(lightPosition.x, lightPosition.y, lightPosition.z,
lightPosition.x, 0, lightPosition.z,
0, 0, 1.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, _lightviewMatrix);
glPopMatrix();
//Draw from the light's point of view
glViewport(0, 0, shadowMapSize, shadowMapSize);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrixf(_projectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(_lightviewMatrix);
glPolygonOffset(8.0f, 1.1f);
glEnable(GL_POLYGON_OFFSET_FILL);
// Check for Error
GLenum error = glGetError();
if(error != 0)
{
printf("Error occured in Shadows::drawFromLight: %d\n", error);
if(GL_STACK_OVERFLOW == error)
printf("GL_STACK_OVERFLOW\n");
if(GL_STACK_UNDERFLOW == error)
printf("GL_STACK_UNDERFLOW\n");
}
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void Shadows::drawWithShadows(int width, int height, Vector position, Vector direction, Vector up, float yPos)
{
// Deactivate buffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
/*glPopAttrib();
glBindTexture(GL_TEXTURE_2D, _depthTextureId);
GLfloat* buffer = new GLfloat[shadowMapSize * shadowMapSize];
glReadPixels(0, 0, shadowMapSize, shadowMapSize, GL_DEPTH_COMPONENT, GL_FLOAT, buffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, shadowMapSize, shadowMapSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, buffer);
std::vector<float> pixbuf;
for(int i = 0; i < shadowMapSize*shadowMapSize; i++)
pixbuf.push_back(buffer);
for(int i = 0; i < pixbuf.size(); i++)
if(pixbuf != 1)
{
std::cout << pixbuf << std::endl;
}
delete[] buffer;*/
//Clear depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Enable colorwriting
glColorMask(1, 1, 1, 1);
//reset viewport
glViewport(0, 0, width, height);
//Reset projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
//Draw from camera's point of view
glMatrixMode(GL_MODELVIEW);
//glLoadMatrixf(viewMatrix);
glLoadIdentity();
gluLookAt(position.x, position.y, position.z,
direction.x, -direction.y, direction.z,
up.x, up.y, up.z);
glTranslatef(0, yPos, 0);
// Check for Error
GLenum error = glGetError();
if(error != 0)
{
printf("Error occured in Shadows::drawWithShadows: %d\n", error);
if(GL_STACK_OVERFLOW == error)
printf("GL_STACK_OVERFLOW\n");
if(GL_STACK_UNDERFLOW == error)
printf("GL_STACK_UNDERFLOW\n");
if(GL_INVALID_OPERATION == error)
printf("GL_INVALID_OPERATION\n");
if(GL_INVALID_VALUE == error)
printf("GL_INVALID_VALUE\n");
}
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void Shadows::drawWithoutShadows()
{
//glActiveTexture(GL_TEXTURE7);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _depthTextureId);
// Get matrix
GLfloat bias[16] = {
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};
// concatinating all matrice into one.
MyMatrix dummy;
dummy = MyMatrix(bias) * MyMatrix(_projectionMatrix) * MyMatrix(_lightviewMatrix);
const GLfloat first[4] = {dummy[0], dummy[4], dummy[8], dummy[12]};
const GLfloat second[4] = {dummy[1], dummy[5], dummy[9], dummy[13]};
const GLfloat third[4] = {dummy[2], dummy[6], dummy[10], dummy[14]};
const GLfloat fourth[4] = {dummy[3], dummy[7], dummy[11], dummy[15]};
//Set up tex coord generation - all 4 coordinates required
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, first);
glEnable(GL_TEXTURE_GEN_S);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, second);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, third);
glEnable(GL_TEXTURE_GEN_R);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_Q, GL_EYE_PLANE, fourth);
glEnable(GL_TEXTURE_GEN_Q);
//Use SGIX_shadow comparison
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_SGIX, true);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
//glBlendEquationEXT(GL_MAX_EXT);
//glEnable(GL_BLEND);
//Set alpha test to discard false comparisons
glAlphaFunc(GL_GEQUAL, 0.99f);
glEnable(GL_ALPHA_TEST);
// Check for Error
GLenum error = glGetError();
if(error != 0)
{
printf("Error occured in Shadows::drawWithoutShadows: %d\n", error);
error = 0;
}
}
// FPS
frame++;
time=glutGet(GLUT_ELAPSED_TIME);
if (time - timebase > 1000) {
printf("FPS:%4.2f\n", frame*1000.0/(time-timebase));
timebase = time;
frame = 0;
}
// Reset to draw again
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
// ++ ---------------------------------------------------------------------------------------------------- ++ //
// First step for shadows
glPushAttrib(GL_ALL_ATTRIB_BITS);
_shadow->drawFromLight(_sun->getPosition());
// Draw the drawables the first time
for(std::list<Drawable*>::iterator it = _drawables.begin(); it != _drawables.end(); it++)
{
(*it)->draw();
}
// ++ ---------------------------------------------------------------------------------------------------- ++ //
// Second step for shadows
_shadow->drawWithShadows(_windowWidth, _windowHeight, _cPosition , _cView, _cUp, _positionY);
_sun->shadowLight();
// Draw the drawables the second time with shadows
for(std::list<Drawable*>::iterator it = _drawables.begin(); it != _drawables.end(); it++)
{
(*it)->draw();
}
// ++ ---------------------------------------------------------------------------------------------------- ++ //
// Second step for shadows
glPushAttrib(GL_ALL_ATTRIB_BITS);
_sun->brightLight();
_shadow->drawWithoutShadows();
// Skybox
//_skybox->draw();
// Draw the drawables the third time with shadows
for(std::list<Drawable*>::iterator it = _drawables.begin(); it != _drawables.end(); it++)
{
(*it)->draw();
}
glPopAttrib();
// Water, grass
//_water->draw();
//_grass->draw();
//_shadow->debug();
// Light out
glDisable(GL_LIGHT0); glDisable(GL_LIGHTING);
// Draw and clear Buffer
glutSwapBuffers();
// Check for Error
GLenum error = glGetError();
if(error == GL_INVALID_OPERATION)
{
printf("Error occured in Viewer: %d\n", error);
error = 0;
}
The sun class only sets the light intesity and holds the position of the light. MyMatrix multiplys the matrices correct.
P.S. I know i should use Shaders for this topic, but it is my first project and i started with the fixed pipeline.