1

I am generating a simple scene with directional light. My aim is to create the scene's shadows through shadow mapping. I have looked all over for help on this topic to no avail. As far as I can tell, my code should be equivalent to that which I have seen in multiple tutorials.

The scene is created perfectly, just without shadows. I suspect that this is a problem with the shadow map texture that is generated (or not) in my program's first render pass. When I draw the rendered texture to a quad, the quad is all white.

My buffer/texture initialisation code is as presented below:

void Renderer :: initBuffers()
{
glGenTextures(1, &SMDepthTexture);
glBindTexture(GL_TEXTURE_2D, SMDepthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE );
glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE );
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);

glBindTexture(GL_TEXTURE_2D, 0);
/*
glGenRenderbuffers(1, &SMRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, SMRenderBuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, SMRenderBuffer);
*/

glGenFramebuffers(1, &SMFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, SMFrameBuffer);
glDrawBuffer(GL_NONE); // No color buffer is drawn to.
glReadBuffer(GL_NONE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, SMDepthTexture, 0);


// Always check that our framebuffer is ok
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
    std :: cerr << "Frame Buffer Status: " << glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) <<"\n";
    exit(0);
}

glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

My display function. (The pass = 1, if(pass == 1) stuff all seems a bit redundant but it was for debugging).

void Renderer :: displayCallback()
{
pass = 1;
if(pass == 1)
{
    glMatrixMode(GL_PROJECTION);
    gluPerspective(FOV,aspect,zNear, zFar);
    glDisable(GL_TEXTURE_2D);
    glBindFramebuffer(GL_FRAMEBUFFER, Renderer :: SMFrameBuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Renderer :: SMDepthTexture, 0);
    glUseProgram(0);
    glViewport(0,0,width,height);
    glClear(GL_DEPTH_BUFFER_BIT);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    display();
}

pass = 2;
if(pass == 2)
{
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glViewport(0,0,width,height);
    glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    glUseProgram(Renderer :: shader_program_pass2);
    Renderer :: uniforms2();
    Renderer :: SMDepthTexture_handle = glGetUniformLocation(Renderer :: shader_program_pass2, "shadowMap");

    glEnable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE7);
    glBindTexture(GL_TEXTURE_2D, Renderer :: SMDepthTexture);
    glUniform1i(Renderer :: SMDepthTexture_handle, 7);

    display();

}

drawMap();
glutSwapBuffers();
}

Finally I try drawing the texture to a screen-filling quad with the following function:

void Renderer :: drawMap()
{
Renderer :: camera_modelview = Globals::camera.getInverseCM();
Renderer :: light_modelview = Renderer :: light_cam.getInverseCM();
if(pass == 1)
{
    glLoadMatrixd(Renderer :: light_cam.getInverseCMGLPointer());
    //glUniformMatrix4fv(Renderer :: camera_modelview_handle_pass1, 1, false, Renderer :: camera_modelview.getGLfloatPointer());
    //glUniformMatrix4fv(Renderer :: light_modelview_handle_pass1, 1, false, Renderer :: light_modelview.getGLfloatPointer());
}
else if(pass == 2)
{
    glUniformMatrix4fv(Renderer :: camera_modelview_handle_pass2, 1, false, Renderer :: camera_modelview.getGLfloatPointer());
    glUniformMatrix4fv(Renderer :: light_modelview_handle_pass2, 1, false, Renderer :: light_modelview.getGLfloatPointer());
}
 glBindFramebuffer(GL_FRAMEBUFFER, 0);
 glUseProgram(0);
 glDisable(GL_LIGHTING);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glOrtho(-width/2,width/2,-height/2,height/2,1,20);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 glColor4f(1,1,1,1);
 glActiveTexture(GL_TEXTURE0);
 glBindTexture(GL_TEXTURE_2D,Renderer :: SMDepthTexture);
 glEnable(GL_TEXTURE_2D);
 glTranslated(0,0,-1);
 glBegin(GL_QUADS);
 glTexCoord2d(0,0);glVertex3f(-width/2,-height/2,0);
 glTexCoord2d(1,0);glVertex3f(width/2,-height/2,0);
 glTexCoord2d(1,1);glVertex3f(width/2,height/2,0);
 glTexCoord2d(0,1);glVertex3f(-width/2,height/2,0);
 glEnd();
 glDisable(GL_TEXTURE_2D);
 glLoadIdentity();
 glEnable(GL_LIGHTING);
 }

I know that a problem that a lot of people have results from having the same texture bound to both the framebuffer and an active texture at the same time. I am pretty sure I have avoided this circumstance.

I will be more than happy to post more code (including shaders) if more detail is required. I appreciate you help so thanks in advance!

  • Is `glBindFramebuffer(GL_FRAMEBUFFER, 0);` in `void Renderer :: drawMap()` intentional? – dari Dec 14 '14 at 20:22
  • glBindFramebuffer*GL_FRAMEBUFFER, 0); Sets the current framebuffer to the standard, draw-to-screen framebuffer. This is needed in order to draw the map to the screen. ... i think – user3335168 Dec 15 '14 at 01:46

0 Answers0