OpenTK GlControl, глубокий пилинг, черный видовой экран - PullRequest
0 голосов
/ 13 октября 2018

Я делаю программу opengl на c #, используя OpenTK, реализуя эффект прозрачности на простых объектах, используя алгоритм глубинного отслаивания.В 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);
}

Inits:

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

Когда я отлаживаю свой exe с помощью отладчиков opengl (RenderDoc и apitrace), он показывает мне, чтоВизуализация в порядке, то есть объекты текстуры заполнены нужными изображениями, но я не знаю, почему сцена черная: (

Может кто-нибудь сказать мне, пожалуйста, что не так с моим кодом? Или любая идея? Спасибозаранее

Если вам нужна дополнительная информация, пожалуйста, скажите мне, чтобы отредактировать вопрос.

1 Ответ

0 голосов
/ 17 февраля 2019

Проблема решена.

Проблема связана с версией OpenGL, и ее эффект находится в функции drawQuadGL(GLuint posIndex) в этой строке:

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

Эта функция может получать два типа ввода,как последний параметр.Он может получить указатель на массив или получить целое число в качестве смещения.Тип указателя устарел начиная с версии OpenGL 3.2.Итак, я изменил последний параметр на 0 и проблема решена.

...