FBO - Render to texture not working

Started by
2 comments, last by mv348 10 years, 8 months ago

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);
 
}
 
Its worth noting that if I say:
cascaded_shadow_map->BindForReading(0); then the texture bound to texture unit 0 (I think its the Position map on my deferred rendering set up) displays perfectly fine. But using the texture unit that the texture CascadedShadowMap::m_shadowMap is bound to, produces a pure black screen, regardless of what I set the depth clear color to in CascadedShadowMap::Clear().
Any ideas would be most appreciated. Thanks!
Advertisement

first thing i'd check is if the texture you are writing to is somehow still bound, on ANY texture unit

can't think of anything else

I don't think thats it. I'm not using the texture for anything else.

(edit) Being doing more testing and it would appear that the depth clearing is being applied to my g-buffer (previously bound frame buffer) and not to the shadow FBO. I can't see why though, I am definitely binding the shadow FBO before clearing the depth buffer.

Fixed a small bug - I forgot to reset the glClearDepth to 1.0f after setting it to 0.25f. But still not working.

I think it has something to do with my gBuffer. My gBuffer has 4 color textures and a depth/stencil texture attached to its FBO. The shadow map FBO has only a depth texture attached. When I do my light pass I have my g-buffer fbo bound, and then I bind the shadow-map's shadow texture to an appropriate texture unit. It appears as if the gBuffer cannot "see" the shadow texture sitting in the unbound FBO. By my understanding I thought this would work but is there some technicality here that I'm not aware of?

This topic is closed to new replies.

Advertisement