I am trying to implement cascaded shadow maps but I am having a strange issue with my FBO. As far as I can tell I am completely unable to write to the attached depth-texture. Even using glClear(GL_DEPTH_BUFFER_BIT) and trying various different clear values, I am unable to see any changes in the texture when I render it to the screen.
Here's a peek at some of my code:
bool CascadedShadowMap::Initialize(unsigned int WindowWidth, unsigned int WindowHeight)
{
m_width = WindowWidth;
m_height= WindowHeight;
// Create the FBO
glGenFramebuffers(1, &m_fbo);
// Create the depth buffer
glGenTextures(1, &m_shadowMap);
glBindTexture(GL_TEXTURE_2D, m_shadowMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, 2 * WindowWidth, 2 * WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 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_COMPARE_MODE, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowMap, 0);
// Disable writes to the color buffer
glDrawBuffer(GL_NONE);
GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (Status != GL_FRAMEBUFFER_COMPLETE) {
vDebugOut("error initializing shadow map! -CasadedShadowMap.cpp");
return false;
}
return true;
}
The debug message is not printed so I know the frame buffer is complete. I also made sure the function is being called.
Here's where the texture should be cleared:
void vGraphics::fillShadowTextureDirectionalCascadedMap()
{
m_noFragmentShader->enable();
glPushAttrib(GL_VIEWPORT_BIT);
cascaded_shadow_map->BindForWriting();
cascaded_shadow_map->Clear();
// Rendering models commented out for now. Trying to get Clear() to work.
/*
...
*/
glPopAttrib();
m_noFragmentShader->disable();
}
[/code]
The methods "BindForReading" and "Clear" shown above are implemented like so:
void CascadedShadowMap::BindForWriting()
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
}
void CascadedShadowMap::Clear()
{
glViewport(0, 0, 2* m_width, 2 * m_height);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glDrawBuffer(GL_NONE);
glDisable(GL_DEPTH_CLAMP);
glClearDepth(0.25f);
glClear(GL_DEPTH_BUFFER_BIT);
}
As you can see I'm setting a lot of options to try to make absolutely certain that nothing will prevent the GBuffer from getting cleared.
Now, just before my light pass, have:
m_dirLightShader->enable();
cascaded_shadow_map->BindForReading(7);
m_dirLightShader->setCascadedShadowUnit(7);
Here's the code for the two functions above.
void vDirectionalLightShader::setCascadedShadowUnit(GLuint textureUnit)
{
glUniform1i(m_unif_casc_shadow_map_id, textureUnit);
}
...
void CascadedShadowMap::BindForReading(GLenum TextureUnit)
{
glEnable(GL_TEXTURE_2D);
glActiveTexture(TextureUnit);
glBindTexture(GL_TEXTURE_2D, m_shadowMap);
}
Now at the end of my fragment shader in my light pass (or "texture render pass" if you will):
float mapSample = (texture(gCascadedShadowMap, TexCoord).x);
FragColor = vec4(mapSample,mapSample,mapSample,1);
}