Jump to content
  • Advertisement
Sign in to follow this  
Aklinger

OpenGL Fixed Pipeline and Shadow Mapping

This topic is 2527 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

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.

Share this post


Link to post
Share on other sites
Advertisement
The lightposition is on (0, 200, 0) and the cube is on (0, 30, 0). The plane under the cube is from (-100,0, -100) to (100, 0, 100). So the shadow should be under the cube.
[attachment=4448:screen.png]

Share this post


Link to post
Share on other sites
[color="#0000FF"][color="#000000"]try a

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);


on the shadow tex's

Share this post


Link to post
Share on other sites
ok, leave it there, its necessary.

now try to upload some random memory garbage as shadow map texture. it should give you some strange result. lets see if the cmp is working.

Share this post


Link to post
Share on other sites
This three lines should do a rnd garbage upload or?
glBindTexture(GL_TEXTURE_2D, _depthTextureId);
GLfloat* buffer = new GLfloat[shadowMapSize * shadowMapSize];
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, shadowMapSize, shadowMapSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, buffer);

The result is a black line through the picture, so i think its no rnd garbage.
[attachment=4450:screen.png]

Share this post


Link to post
Share on other sites
Switch to srand timer and try to run through a (rand()%10000000)/1000.0 on your memory area.

Share this post


Link to post
Share on other sites
Ok, the result ist the same as in the first picture. (Most of the time, sometimes, there are lines as in picture two)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!