c++openglframebufferdepth-bufferdepth-testing

Depth test discards fragments on custom framebuffer


In my programm I render multiple matrices to different framebuffers. At the end I render the textures created by the framebuffers to three 2D quads. The problem is that the Depth test discards all fragments of the custom framebuffers except for the first one that gets rendered.

Here I initialize the framebuffers:

unsigned int* framebufferArray = new unsigned int[(input_view.size()+output_view.size()+1)];
unsigned int* framebufferTextureArray = new unsigned int[(input_view.size() + output_view.size() + 1)];
for (int i = 0; i < (input_view.size()+output_view.size()+1); ++i)
{
    unsigned int framebuffer;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    unsigned int fBufferTexture;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    unsigned int fBufferTexture;
    glGenTextures(1, &fBufferTexture);
    glBindTexture(GL_TEXTURE_2D, fBufferTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window_width, window_height, 0, GL_RGB, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fBufferTexture, 0);

    unsigned int rbo;
    glGenRenderbuffers(1, &rbo);
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, window_width, window_height); // use a single renderbuffer object for both a depth AND stencil buffer.
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo); // now actually attach it
    // now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        printf("ERROR::FRAMEBUFFER:: Framebuffer is not complete!");
    framebufferArray[i] = framebuffer;
    framebufferTextureArray[i] = fBufferTexture;
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
}

And here I render the matrices:

for (int i = 0; i < input_view.size(); ++i)
    {
        float alphaFactor = 1;

        glBindFramebuffer(GL_FRAMEBUFFER, framebufferArray[i + 1]);
        glClearColor(bgColor[0], bgColor[1], bgColor[2], 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDisable(GL_BLEND);
        glEnable(GL_DEPTH_TEST);
        glDepthMask(GL_TRUE);

        glUseProgram(solidShaderID);
        std::vector<float> Cachecolor = { CacheColorInfo[cacheLayerCount - 1][0], CacheColorInfo[cacheLayerCount - 1][1], CacheColorInfo[cacheLayerCount - 1][2] };

        glBindTexture(GL_TEXTURE_2D, solidTexture);
        mat4 translationMatrix = glm::translate(mat4(1.0f), glm::vec3(ThreadTranslateVector[0], ThreadTranslateVector[1], ThreadTranslateVector[2] + 6));
        glUniformMatrix4fv(glGetUniformLocation(solidShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
        glUniform3fv(glGetUniformLocation(solidShaderID, "tint"), 1, &Cachecolor[0]);
        glUniform1f(glGetUniformLocation(solidShaderID, "focusFac"), focusLayerFac[cacheLayerCount]);

        glBindVertexArray(inputViewVAOs[i][1]);
        glDrawArrays(GL_TRIANGLES, 0, inputViewVertexCountInfo[i][1] * 3);
        glBindVertexArray(0);

        glDepthMask(GL_FALSE);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glUseProgram(transShaderID);
        glBindTexture(GL_TEXTURE_2D, transparentTexture);
        translationMatrix = glm::translate(mat4(1.0f), vec3(0, matsizeN, 0));
        glUniformMatrix4fv(glGetUniformLocation(transShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
        glUniform3fv(glGetUniformLocation(transShaderID, "tint"), 1, &matColor[0]);
        glUniform1f(glGetUniformLocation(transShaderID, "focusFac"), focusLayerFac[cacheLayerCount]);
        glUniform1fv(glGetUniformLocation(transShaderID, "alphaFac"), 1, &alphaFactor);

        glBindVertexArray(inputViewVAOs[i][0]);
        glDrawArrays(GL_TRIANGLES, 0, inputViewVertexCountInfo[i][0] * 3);
        glBindVertexArray(0);
    }

Here I render the three quads:

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    glClearColor(bgColor[0], 0.3, bgColor[2], 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_BLEND);


    glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[0]);
    glUseProgram(matrix2dShaderID);
    mat4 translationMatrix = glm::mat4(1.0f);
    //translationMatrix = glm::translate(translationMatrix, glm::vec3((float)(window_width - 200) / (float)window_width, 0, 0));
    translationMatrix = glm::translate(translationMatrix, glm::vec3(0,0.6,0));
    translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize/(float)window_height,(float)viewSize/(float)window_height,1));
    glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);

    glBindVertexArray(quadVAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);

    glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[1]);
    glUseProgram(matrix2dShaderID);
    translationMatrix = glm::mat4(1.0f);
    translationMatrix = glm::translate(translationMatrix, glm::vec3(0, -0.6, 0));
    translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize / (float)window_height, (float)viewSize / (float)window_height, 1));
    glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);

    glBindVertexArray(quadVAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);

    glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[2]);
    glUseProgram(matrix2dShaderID);
    translationMatrix = glm::mat4(1.0f);
    translationMatrix = glm::translate(translationMatrix, glm::vec3(0,0, 0));
    translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize / (float)window_height, (float)viewSize / (float)window_height, 1));
    glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);

    glBindVertexArray(quadVAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);

This is the output with depth testing enabled:

and this with depth testing disabled:

It seems like the depth test just discards everything after the first framebuffer.


Solution

  • The issue is caused by disable writing into the depth buffer:

    glDepthMask(GL_FALSE);
    

    glDepthMask sets a global state and specifies whether a depth buffer is enabled or disabled for writing. This also effects operations glClear. If the depth buffer is disabled for writing, then depth buffer can't be cleared, too.
    Note, the state is global and kept until it is changed again. When glClear is called then the current state of the glDepthMask flag is evaluated.

    Enable the depth buffer for writing, before clear:

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
    glClearColor(bgColor[0], 0.3, bgColor[2], 1.0f);
    
    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);