Отрисовка FBO разного размера

У меня возникла проблема при использовании FBO.

У меня размер окна 1200х300.

Когда я создаю FBO размером 1200x300, все в порядке.

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

FBO того же размера, что и окно:

Тот же размер

FBO в два раза больше (заметна обрезка треугольника):

Другой размер

Я визуализирую эти два треугольника в FBO, затем визуализирую полноэкранный четырехугольник с текстурой FBO поверх него. Я очищаю FBO этим сосново-зеленым цветом, поэтому я точно знаю, что все это пустое пространство на второй картинке на самом деле исходит от FBO.

// init() of the program
albedo = new RenderTarget(2400, 600, 24 /*depth*/);  // in first case, params are 1200, 300, 24

// draw()
RenderTarget::set(albedo);   // render to fbo
RenderTarget::clearColor(0.0f, 0.3f, 0.3f, 1.0f);
RenderTarget::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// render triangles ...
glDrawArrays(GL_TRIANGLES, 0, 6);

// now it's time to render a fullscreen quad
RenderTarget::set();   // render to back-buffer
RenderTarget::clearColor(0.3f, 0.0f, 0.0f, 1.0f);
RenderTarget::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, albedo->texture());
glUniform1i(albedoUnifLoc, 0);
RenderTarget::drawFSQ();   // draw fullscreen quad

У меня нет никаких камер, я нигде не использую glViewport, я всегда отправляю координаты примитивов для рисования в пространстве единичных квадратов (координаты x и y находятся в диапазоне [-1,1]).

Вопрос, что я делаю не так и как это исправить?

Кроме того, вопрос: glViewport каким-либо образом связан с текущим фреймбуфером? Насколько я понял, эта функция просто используется для установки области прямоугольника в окне, в котором будет происходить рисование.

Любое предложение будет принято с благодарностью. Я попытался найти проблему в Интернете, единственная похожая вещь была в это ТАК вопрос, но мне это не помогло.


person Abstract Algorithm    schedule 20.11.2014    source источник


Ответы (1)


Вам нужно вызвать glViewport() с размером вашей цели рендеринга. Единственный раз, когда вы можете уйти, не вызывая его, - это когда вы выполняете рендеринг в окно, и размер окна никогда не изменяется. Это потому, что окно просмотра по умолчанию соответствует начальному размеру окна. Из спецификации:

В начальном состоянии w и h устанавливаются равными соответственно ширине и высоте окна, в котором GL должен выполнять рендеринг.

Если вы хотите выполнить рендеринг в FBO с размером, отличным от вашего окна, вы должны вызвать glViewport() с размером FBO. И когда вы вернетесь к рендерингу в окно, вам нужно снова вызвать glViewport() с размером окна.

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

person Reto Koradi    schedule 20.11.2014
comment
Это сработало, ни с того ни с сего. Спасибо. Казалось, что у меня были некоторые проблемы с внутренним кодом, но ваше решение было действительно хорошим. - person Abstract Algorithm; 12.12.2014