c++ - 深度测试丢弃自定义帧缓冲区上的片段

标签 c++ opengl framebuffer depth-buffer depth-testing

在我的程序中,我将多个矩阵渲染到不同的帧缓冲区。最后,我将帧缓冲区创建的纹理渲染为三个 2D 四边形。问题是深度测试丢弃了自定义帧缓冲区的所有片段,除了第一个被渲染的片段。

这里我初始化帧缓冲区:

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);
}

在这里我渲染矩阵:

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);
    }

这里我渲染了三个四边形:

    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);

这是启用深度测试的输出:

并且在禁用深度测试的情况下:

似乎深度测试只是丢弃了第一个帧缓冲区之后的所有内容。

最佳答案

问题是由于禁用写入深度缓冲区引起的:

glDepthMask(GL_FALSE);

glDepthMask设置全局状态并指定是否启用或禁用深度缓冲区进行写入。这也会影响操作 glClear .如果深度缓冲区被禁止写入,那么深度缓冲区也不能被清除。
请注意,状态是全局的,并且会一直保留到再次更改为止。当调用 glClear 时,将评估 glDepthMask 标志的当前状态。

在清除之前启用深度缓冲区进行写入:

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);

关于c++ - 深度测试丢弃自定义帧缓冲区上的片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57571377/

相关文章:

opengl - DirectX/Cuda/OpenGL 的总/纹理可访问内存

opengl - 具有多种颜色附件的多采样帧缓冲区的分辨率

c++ - 如何在结构中动态分配内存?

opengl - 如何在 GTX 560 及更高版本上使用 OpenGL 进行立体 3D?

c++ - GLM - 是否保证 vector 和矩阵的内存等同于它们的 GLSL 对应项?

android - framebuffer OES 不完整,android

c++ - Qt:为什么我的图像背景在 LinuxFb 上是绿色的?

c++ - 如何将模板类用于容器的容器?

c++ - 如何使用可变终点迭代基于范围的 for 循环

c++ - 指向指针的指针和运算符的地址如何工作?