【问题标题】:OpenTK GlControl, depth peeling, black viewportOpenTK GlControl,深度剥离,黑色视口
【发布时间】:2018-10-13 12:58:27
【问题描述】:

我正在使用 OpenTK 在 c# 中制作一个 opengl 程序,对简单对象实现透明效果,使用深度剥离算法。有一个来自 NVIDIA 的网络深度剥离示例代码,在 c++ 中,我对其进行了简化并且工作正常。但是当我将代码移植到 c# 时,视口变成纯黑色。我多次对比了c++和c#代码,不认为代码有什么问题或者意外差异。

渲染循环:

while (!done)
{
    /* --------------------------------------------------------------------- */
    /* 1. Peel the first layer                                               */
    /* --------------------------------------------------------------------- */

    glBindFramebuffer(GL_FRAMEBUFFER, frontColorBlenderFboId);
    glDrawBuffer(GL_COLOR_ATTACHMENT0);

    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_DEPTH_TEST);

    glUseProgram(program_shaderPeelingInit);
    // setUniform1f()
    glUniform1f(glGetUniformLocation(program_shaderPeelingInit, "uAlpha"), opacity);
    drawModel(program_shaderPeelingInit);
    glUseProgram(0);

    /* --------------------------------------------------------------------- */
    /* 2. Depth Peeling + Blending                                           */
    /* --------------------------------------------------------------------- */

    for (int32_t layer = 1; true && layer < MAX_PEELED_LAYERS; layer++)
    {
        /* --------------------------------------------------------------------- */
        /* 2.1. Peel the next depth layer                                        */
        /* --------------------------------------------------------------------- */

        int32_t currId = layer % 2;
        int32_t prevId = 1 - currId;

        glBindFramebuffer(GL_FRAMEBUFFER, frontFboId[currId]);
        glDrawBuffer(GL_COLOR_ATTACHMENT0);

        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glDisable(GL_BLEND);
        glEnable(GL_DEPTH_TEST);

        glBeginQuery(GL_SAMPLES_PASSED, queryId);

        glUseProgram(program_shaderPeelingPeel);
        // bindTextureRect()
        glUniform1i(glGetUniformLocation(program_shaderPeelingPeel, "DepthTex"), 0);
        glActiveTexture(GL_TEXTURE0 + 0);
        glBindTexture(0x84F5/*GL_TEXTURE_RECT*/, frontDepthTexId[prevId]);
        // setUniform1f()
        glUniform1f(glGetUniformLocation(program_shaderPeelingPeel, "uAlpha"), opacity);
        drawModel(program_shaderPeelingPeel);
        glUseProgram(0);

        glEndQuery(GL_SAMPLES_PASSED);

        /* --------------------------------------------------------------------- */
        /* 2.2. Blend the current layer                                          */
        /* --------------------------------------------------------------------- */

        glBindFramebuffer(GL_FRAMEBUFFER, frontColorBlenderFboId);
        glDrawBuffer(GL_COLOR_ATTACHMENT0);

        glEnable(GL_BLEND);
        glDisable(GL_DEPTH_TEST);

        // UNDER operator
        glBlendEquation(GL_FUNC_ADD);
        glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE,
            GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);

        glUseProgram(program_shaderPeelingBlend);
        // bindTextureRect()
        glUniform1i(glGetUniformLocation(program_shaderPeelingBlend, "TempTex"), 0);
        glActiveTexture(GL_TEXTURE0 + 0);
        glBindTexture(0x84F5/*GL_TEXTURE_RECT*/, frontColorTexId[currId]);
        // renderFullscreenQuad()
        glUniformMatrix4fv(glGetUniformLocation(program_shaderPeelingBlend, "uModelViewMatrix"), 1, false, glm::value_ptr(glm::mat4()));
        drawQuadGL(0);
        glUseProgram(0);

        glDisable(GL_BLEND);

        GLuint sample_count;
        glGetQueryObjectuiv(queryId, GL_QUERY_RESULT, &sample_count);
        if (sample_count == 0)
        {
            break;
        }
    }

    /* --------------------------------------------------------------------- */
    /* 3. Compositing Pass                                                   */
    /* --------------------------------------------------------------------- */

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glDrawBuffer(GL_BACK);
    glDisable(GL_DEPTH_TEST);

    glUseProgram(program_shaderPeelingFinal);
    // setUniform3f()
    glUniform3f(glGetUniformLocation(program_shaderPeelingFinal, "uBackgroundColor"),
        backgroundColor[0], backgroundColor[1], backgroundColor[2]);
    // bindTextureRect()
    glUniform1i(glGetUniformLocation(program_shaderPeelingFinal, "ColorTex"), 0);
    glActiveTexture(GL_TEXTURE0 + 0);
    glBindTexture(0x84F5/*GL_TEXTURE_RECT*/, frontColorBlenderTexId);
    // renderFullscreenQuad()
    glUniformMatrix4fv(glGetUniformLocation(program_shaderPeelingFinal, "uModelViewMatrix"), 1, false, glm::value_ptr(glm::mat4()));
    drawQuadGL(0);
    glUseProgram(0);
}

初始化:

glGenTextures(2, frontDepthTexId);
glGenTextures(2, frontColorTexId);
glGenFramebuffers(2, frontFboId);

for (int i = 0; i < 2; i++)
{
    glBindTexture(GL_TEXTURE_RECTANGLE, frontDepthTexId[i]);
    glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT32F_NV,
        WIDTH, HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

    glBindTexture(GL_TEXTURE_RECTANGLE, frontColorTexId[i]);
    glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, WIDTH, HEIGHT,
        0, GL_RGBA, GL_FLOAT, 0);

    glBindFramebuffer(GL_FRAMEBUFFER, frontFboId[i]);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
        GL_TEXTURE_RECTANGLE, frontDepthTexId[i], 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
        GL_TEXTURE_RECTANGLE, frontColorTexId[i], 0);
}

glGenTextures(1, &frontColorBlenderTexId);
glBindTexture(GL_TEXTURE_RECTANGLE, frontColorBlenderTexId);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, WIDTH, HEIGHT,
    0, GL_RGBA, GL_FLOAT, 0);

glGenFramebuffers(1, &frontColorBlenderFboId);
glBindFramebuffer(GL_FRAMEBUFFER, frontColorBlenderFboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
    GL_TEXTURE_RECTANGLE, frontDepthTexId[0], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
    GL_TEXTURE_RECTANGLE, frontColorBlenderTexId, 0);

绘制函数:

void drawModel(GLuint program)
{
    glUniformMatrix4fv(glGetUniformLocation(program, "uNormalMatrix"), 1, false, glm::value_ptr(normalMat));
    glUniformMatrix4fv(glGetUniformLocation(program, "uModelViewMatrix"), 1, false, glm::value_ptr(mvp));

    glBindVertexArray(cubesVAO);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);

    numGeoPasses++;
}

void drawQuadGL(GLuint posIndex)
{
    const float position[] = {
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f, 1.0f,
        1.0f, 1.0f,
    };

    glVertexAttribPointer(posIndex, 2, GL_FLOAT, false, 2 * sizeof(float), position);
    glEnableVertexAttribArray(posIndex);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDisableVertexAttribArray(posIndex);
}

当我使用 opengl 调试器(RenderDoc 和 apitrace)调试我的 exe 时,它​​显示渲染效果很好,即纹理对象充满了所需的图像,但我不知道为什么场景是黑色的 :(

谁能告诉我我的代码有什么问题?或者有什么想法?提前致谢

如果需要任何其他详细信息,请告诉我编辑问题。

【问题讨论】:

  • c++ 和c# 之间肯定存在一些语言差异。我猜,但缓冲区结构可能不同。
  • @John 你指的是哪个缓冲区? VBO, FBO ... ?

标签: c# opengl transparency opentk


【解决方案1】:

问题解决了。

问题在于OpenGL版本,它的效果在函数drawQuadGL(GLuint posIndex)这一行:

glVertexAttribPointer(posIndex, 2, GL_FLOAT, false, 2 * sizeof(float), position);

这个函数可以得到两种类型的输入,作为最后一个参数。它可以获取指向数组的指针,或者获取整数作为偏移量。从 OpenGL 版本 3.2 开始不推荐使用指针类型。于是,我把最后一个参数改成了0,问题就解决了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多