c++openglframebuffershadow-mapping

Setting up GL_TEXTURE_2D_ARRAY, framebuffer incomplete


For cascaded shadow mapping I'm trying to use a GL_TEXTURE_2D_ARRAY for the individual shadow maps. However following tutorials found online and even looking up things in a textbook I can't seem to create a working framebuffer, as it always errors with GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT.

The code:

glGenFramebuffers(1, &m_DepthMap.m_FrameBuffer);


glGenTextures(1, &m_DepthMap.m_DepthTexture);
glBindTexture(GL_TEXTURE_2D_ARRAY, m_DepthMap.m_DepthTexture);
glTexImage3D(
    GL_TEXTURE_2D_ARRAY,
    0,
    GL_DEPTH_COMPONENT32F,
    Renderer::m_ShadowMapResolution,
    Renderer::m_ShadowMapResolution,
    3,
    0,
    GL_DEPTH_COMPONENT,
    GL_FLOAT,
    nullptr);
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_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);

glBindFramebuffer(GL_FRAMEBUFFER, m_DepthMap.m_FrameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_DepthMap.m_DepthTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);

const int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
    std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!";
    throw 0;
}

Sources that tell me that this should be correct:

https://people.inf.elte.hu/plisaai/pdf/OpenGL%20Insights.pdf , page 264

https://johanmedestrom.wordpress.com/2016/03/18/opengl-cascaded-shadow-maps/

What am I doing wrong here? Why is the framebuffer incomplete?


Solution

  • The tutorial you cited has led you astray.

    A 2D texture is not the same thing as a 2D array texture. You can either attach a specific array layer (of a specific mipmap level) to a framebuffer, or attach all of the array images in a mipmap. In neither of these cases can you call glFramebufferTexture2D to do this for an array texture (which is why you should be checking for OpenGL errors in one way or another, as this function should have errored out).

    In any case, if you want to attach a specific array layer to the framebuffer, then you want to use glFramebufferTextureLayer. If you want to attach it as a layered attachment (because you're doing layered rendering), then you'd use glFramebufferTexture.