Невозможно получить простой фрейм-буфер, отображаемый на квадроцикле - PullRequest
2 голосов
/ 01 апреля 2019

Это моя первая попытка использовать кадровые буферы вместо использования по умолчанию (а затем нарисовать текстуру кадрового буфера в кадровый буфер по умолчанию). Я делаю что-то не так по пути, и я не уверен, что. Я перечислю каждый шаг, который я делаю, так как этот пример довольно близок к MCVE.

Все состояния glEnable (), которые я хочу, установлены правильно, и это не является проблемой, согласно RenderDoc. Я зарегистрировал обратный вызов с glDebugMessageCallback и не получаю ошибок. Также я прикрепляю текстуру глубины / трафарета, но не использую ее в этом примере (но буду использовать ее, когда исправлю эту проблему).

Мой код, по сути, выглядит следующим образом (все последовательно, поэтому если на шаге X есть привязка, то она также связана с шагом X + 1):

0) Создание VBO / VAO / шейдерной программы для рисования текстуры FBO

// This is fine according to RenderDoc

1) Создайте фрейм-буфер с текстурой, которую мы будем рендерить, и текстурой глубины / трафарета:

glGenFramebuffers(1, &fbo);

// Indenting added to this MCVE only
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

    [same as above but now with a depth24/stencil8 texture]

    assert GL_FRAMEBUFFER_COMPLETE (which returns true)
glBindFramebuffer(GL_FRAMEBUFFER, 0);

2) Фаза рендеринга, очистка кадрового буфера по умолчанию

glClearColor(0.1, 0.1, 0.1, 1.0)
glClear(GL_COLOR_BUFFER_BIT)
glViewport(0, 0, w, h)

3) Свяжите новое FBO и очистите его, прежде чем мы начнем рисовать квад

glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glClearColor(0.0, 0.0, 0.0, 0.0)
glClear(color/stencil/depth bits)
glViewport(0, 0, w, h)

4) Нарисуйте четырехугольник в новый кадровый буфер двумя треугольниками

// Not needed in the MCVE but will be required in the actual
// application, so I'll put it in here in the odd case this
// is somehow important
glClearDepth(1.0);

// Do I need to bind the depth/stencil texture here as well?
glBindTexture(GL_TEXTURE_2D, texture);
    bind shader program
        set mvp uniform
        bind vbo
            upload 2 triangles to vbo
            // My goal is to draw the quad on the second
            // framebuffer here
            glDrawArrays(...)
        unbind vbo
    unbind shader
glBindTexture(GL_TEXTURE_2D, 0);

5) Нарисуйте текстуру FB в буфере кадров по умолчанию

glBindFramebuffer(GL_FRAMEBUFFER, 0);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
    // QUESTION: Do I also need to bind the depth/stencil here
    //           if I was planning to use it? Right now I do not
    //           and I'm wondering if that's a mistake
    bind second shader program
        create vbo/vao
        bind vbo
            fill up vbo with a quad to draw the framebuffer texture
            glDrawArrays(...)
        unbind vbo
    unbind second shader program
glBindTexture(GL_TEXTURE_2D, 0);

На последнем шаге не задано ни одной формы, потому что я даю ей координаты NDC и не нуждаюсь в преобразовании.

Когда я запускаю программу и поднимаю кадровый буфер, я могу сказать, что он делает что-то , потому что мой FPS падает с 4000-5000 кадров в секунду до примерно 2000 кадров в секунду, и я начинаю получать свист катушки, и когда Я переключаю рендеринг кадрового буфера, затем он возвращается к 4k-5k fps, и свист катушки исчезает.

Однако ничто не рисует ...

Я открыл его в RenderDoc, чтобы посмотреть, что случилось, и вот что он мне говорит:

1) Все мои данные (VBO, область просмотра, чистые цвета и т. Д.) Соответствуют моим желаниям. Если есть какие-либо ошибки в данных, которые вы увидите, то это неправильное понимание OpenGL с моей стороны, а не ошибка кода.

2) Похоже, что результаты как второго, так и стандартного меша кадрового буфера находятся за пределами усеченной области, я что-то не так сделал?

Мой первый шаг - нарисовать материал на втором кадровом буфере (я рендую квад в окне просмотра 800x600, где я хочу заполнить верхнюю половину (от 0,0 до 800,300, где орто-матрица предназначена для верхний левый - начало координат)), а позже я нарисую на нем текстуру для этого «второго кадрового буфера». Итак, для второго кадрового буфера ... вот что я вижу:

enter image description here

enter image description here

На самом деле существует промежуток между белым квадратом (который, как я полагаю, является усечением вида), который заставляет меня задуматься, рисую ли я два треугольника против часовой стрелки в неправильном Z. Рендердок говорит, что я рисую их в Координаты NDC Z равны -0,60, поэтому я подумал, что это в диапазоне, поскольку куб NDC от -1 до +1 по всем 3 осям.

Сам квадр соответствует этому, как видно на втором изображении, но часть меня удивляется, если я как-то сделал что-то не так с моей орфографической матрицей ... однако, если значение NDC Z -0.60 в порядке, тогда Я предполагаю, что трансформация делает то, что я хочу.

RenderDoc говорит, что квад рендерится согласно текстуре кадрового буфера , так что это хорошо. Для отладки я сделал:

// Force any draw we have to be red and max alpha to debug it
fragColor.x = 1.0;
fragColor.w = 1.0;

и мы получаем это как вывод второго кадрового буфера в соответствии с RenderDoc:

enter image description here

так это хорошо! Кажется, я правильно рисую квад на втором кадровом буфере.

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

Чтобы попытаться отладить это, я сделал то же самое для шейдера со стандартным кадровым буфером (за исключением того, что я сделаю зеленый вместо красного в фрагментном шейдере). Тем не менее, зеленый не был нарисован, но RenderDoc говорит, что я все сделал правильно. Вот информация:

Вершинный шейдер:

    #version 440 core

    layout(location = 0) in vec3 pos;
    layout(location = 1) in vec2 uv;

    out vec2 uvFrag;

    void main() {
        uvFrag = uv;
        gl_Position = vec4(pos, 1.0);
    }

Фрагмент шейдера:

    #version 440

    in vec2 uvFrag;

    out vec4 fragColor;

    uniform sampler2D framebufferTexture;

    void main() {
        fragColor = texture(framebufferTexture, uvFrag);

        // Debug whether its actually even drawing the quad
        fragColor.y = 1.0;
        fragColor.w = 1.0;
    }

Сетчатый выход:

enter image description here

Я не уверен, где я облажался. Координаты NDC Z -0,90 в порядке? Если это так, то два треугольника, из которых состоит четырехугольник, попадают туда ... но они не окрашены. Из-за отладки с зеленым / альфа на 1.0, даже если текстура как-то не так, я должен получить хотя бы что-то при рисовании.

Состояние конвейера в порядке, замена буферов работает для других вещей, так что я почти уверен, что не делаю там ничего плохого. Ошибки GL не найдены.

Есть какие-нибудь предположения о том, почему треугольники не выбираются кадровым буфером по умолчанию? Я получаю только чистый цвет для стандартного кадрового буфера, что заставляет меня задаться вопросом, связываю ли я вещи в неправильном месте или я испортил повторную привязку стандартного кадрового буфера, или координаты NDC в последнем изображении, которое я разместил, неправильно, или если это что-то еще, я не знаю.

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

Перед рендерингом 2-го прохода тест глубины должен быть отключен

glDisable(GL_DEPTH_TEST);

или буфер глубины цели рендеринга (кадровый буфер по умолчанию) должен быть очищен:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Обратите внимание, что по умолчанию функция глубины равна GL_LESS, поэтому проверка глубины не будет выполнена, если буфер глубины не "очищен", на 1,0. Даже если проверка глубины завершается успешно в 1-м кадре, во 2-м кадре буфер цвета очищается, проверка глубины не пройдена и ничего не отображается.

1 голос
/ 01 апреля 2019
// Do I need to bind the depth/stencil texture here as well?
glBindTexture(GL_TEXTURE_2D, texture);

На самом деле, вы вообще ничего не должны связывать. Если вы привязываете текстуру к текстурному блоку, вы можете создать петлю обратной связи (если текстурный блок взят из шейдеров). Разрешено оставлять целевую текстуру рендеринга связанной, если конфигурация конвейера не будет считываться с нее, но в случае «не будет отображаться» лучше убедиться, что целевые текстуры рендеринга не находятся в «читаемом» состоянии, когда рисунок к.

...