OpenGL рендеринг в текстуру через FBO - некорректное отображение по сравнению с нормальной текстурой - PullRequest
7 голосов
/ 09 марта 2012

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

Моя полная программа примера (2D только сейчас!) Здесь:

http://pastebin.com/hSvXzhJT

См. Ниже некоторые описания.

Я создаю текстурный объект rgba 512x512, привязываю его к FBO. На этом этапе не требуется никаких буферов глубины или другого, строго 2D.

Следующие чрезвычайно простые шейдеры отрисовывают эту текстуру:

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

varying vec2 vPos; attribute vec2 aPos;
void main (void) {
    vPos = (aPos + 1) / 2;
    gl_Position = vec4(aPos, 0.0, 1.0);
}

В aPos это просто получает VBO, содержащее 4 координаты xy для четырехугольника (-1, -1 :: 1, -1 :: 1, 1 :: -1, 1)

Таким образом, хотя теоретически разрешение кадрового буфера должно быть 512x512, очевидно, шейдер отображает свою «текстуру» в «квадрате полного (выключенного) экрана», следуя парадигме координат GLs -1..1.

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

varying vec2 vPos;
void main (void) {
    gl_FragColor = vec4(0.25, vPos, 1);
}

Таким образом, он устанавливает полностью непрозрачный цвет с красным, равным 0,25, и зеленым / синим в зависимости от x / y в диапазоне от 0 до 1.

На данный момент я предполагаю, что отображается текстура 512x512, показывающая только полноэкранный квадроцикл -1..1 с фрагментным оттенком зеленого / синего от 0..1.

Так что это мои настройки вне экрана. На экране у меня есть еще один реально видимый полноэкранный квад с 4 координатами xyz {-1, -1, 1 ::: 1, -1, 1 ::: 1, 1, 1 ::: -1, 1, 1} Опять же, сейчас это 2D, поэтому нет матриц и поэтому z всегда 1.

Этот четырехугольник нарисован другим шейдером, просто отображающим данную текстуру в стиле учебника GL-101. В приведенном выше примере программы у меня есть простой булевский переключатель doRtt, когда он имеет значение false (по умолчанию), рендеринг в текстуру не выполняется вообще, и этот шейдер просто показывает использует texture.jpg из текущего каталога.

Этот режим doRtt = false показывает, что второй экранный quad-рендеринг является «правильным» для моих текущих требований и выполняет текстурирование так, как я хочу: повторяется дважды по вертикали и дважды по горизонтали (позже будет зафиксировано, повторить это только для тестирования здесь), иначе масштабирование без фильтрации текстур или mipmapping.

Поэтому независимо от того, как изменяется размер окна (и, следовательно, порта просмотра), мы всегда видим полноэкранный квад с одной текстурой, повторяемой дважды по горизонтали, дважды по вертикали.

Теперь, с doRtt = true, второй шейдер все еще выполняет свою работу, но текстура никогда не полностью корректно масштабируется - или прорисовывается, в этом я не уверен, так как, к сожалению, мы не можем просто сказать: "Эй, спаси это FBO на диск для отладки ".

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

(A) также: текстура 512x512 создана правильно, но не правильно отображается моим кодом (но тогда почему при doRtt = false любой заданный файл texture.jpg, использующий точно такой же простой текстурированный квад-шейдер, показывает нормально? )

(B) или: текстура 512x512 отображается неправильно, и каким-то образом шейдер rtt фрагмента изменяет свой вывод в зависимости от разрешения окна - но почему? Внеэкранный четырехугольник всегда равен -1..1 для x и y, вершинный шейдер всегда отображает это на координаты фрагмента 0..1, текстура RTT всегда остается на 512x512 для этого простого теста!

Обратите внимание, ОБА за пределами экрана и за экраном никогда не меняют свои координаты и всегда находятся "на весь экран" (-1..1 в обоих измерениях).

Опять же, это должно быть так просто. Что, черт возьми, мне не хватает?

Спецификации: OpenGL 4.2 (но код, очевидно, не нуждается в каких-либо функциях 4.2!), Nvidia Quadro 5010M, openSuse 12.1, 64-битная версия, Golang Weekly 22-Feb-2012.

1 Ответ

11 голосов
/ 09 марта 2012

Прежде всего - попробуйте проверить ошибки OpenGL. Вызывайте glGetError () после каждой функции OpenGL. Также вы должны установить правильный видовой экран для рисования. Перед отрисовкой в ​​FBO вызовите glViewport (0, 0, 512, 512). Перед рисованием на экране вызовите glViewport (0, 0, display_width, display_height).

Также нет необходимости связывать rttFrameTex при рендеринге с использованием FBO. Связывание текстур необходимо только тогда, когда вы читаете текстуру в шейдере.

...