OpenTK GlControl,深度剥离,黑色视口

时间:2018-10-13 12:58:27

标签: c# opengl transparency opentk

我正在使用OpenTK在c#中制作一个opengl程序,并使用深度剥离算法在简单对象上实现透明效果。 NVIDIA提供了一个深度剥离Web的示例代码,在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时,它显示出渲染效果很好,即纹理对象充满了所需的图像,但是我不知道为什么场景是黑色的:(< / p>

有人可以告诉我我的代码有什么问题吗?还是有什么主意?预先感谢

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

1 个答案:

答案 0 :(得分:0)

问题解决了。

问题与OpenGL版本有关,其作用在此行的功能drawQuadGL(GLuint posIndex)中:

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

此函数可以获得两种类型的输入,作为最后一个参数。它可以获取指向数组的指针,也可以获取整数作为偏移量。从OpenGL 3.2版开始不推荐使用指针类型。因此,我将最后一个参数更改为0并解决了问题。