Вам нужно вызывать glViewport каждый раз, когда вы связываете буфер кадра с другим разрешением?

У меня есть программа с примерно 3 фреймбуферами разного размера. Я инициализирую их в начале, задаю им соответствующую цель рендеринга и изменяю размер окна просмотра для каждого из них.

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

Это обязательно или что-то еще в программе виновато? Это делается в каждом кадре, поэтому я беспокоюсь, что если мне не придется этого делать, возникнут небольшие ненужные накладные расходы.


person Goldboa    schedule 15.11.2015    source источник


Ответы (2)


Первоначально я думал, что вам нужно вызывать glViewPort только тогда, когда вы инициализируете буфер кадра, однако это создает проблемы в моей программе, поэтому я предполагаю, что это неправильно?

Да, это неправильное предположение (вероятно, подпитываемое бесчисленным количеством плохих руководств, в которых glViewport неуместен).

glViewport всегда относится к коду рисования. Вы всегда вызываете glViewport с правильными параметрами непосредственно перед тем, как собираетесь рисовать что-то в фреймбуфере. Параметры, заданные glViewport, используются в конвейере преобразования, поэтому glViewport следует рассматривать как команду, аналогичную glTransform (в фиксированном конвейере функций) или glUniform.

person datenwolf    schedule 15.11.2015
comment
Благодарю вас! :) Во всех туториалах я использовал такое же разрешение в фреймбуферах, как и в окне. - person Goldboa; 15.11.2015

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

Если вы посмотрите, например, на спецификацию OpenGL 3.3, раздел 6.2, озаглавленный «Таблицы состояний», начиная со страницы 278, содержит таблицы со всем состоянием, показывающие область действия каждой части состояния:

  • В Табл. 6.23 на стр. 299 перечислены «состояния для каждого объекта фреймбуфера». Единственным перечисленным состоянием являются буферы отрисовки и буфер чтения. Если бы область просмотра была частью состояния фреймбуфера, она была бы указана здесь.
  • Окно просмотра указано в таблице 6.8 «Состояние трансформации». Это глобальное состояние, не связанное с каким-либо объектом.

OpenGL 4.1 представляет несколько окон просмотра. Но они по-прежнему являются частью состояния глобальной трансформации.

Если вы задаетесь вопросом, почему это так, единственный реальный ответ состоит в том, что это было определено таким образом. Глядя на графический конвейер, это имеет смысл. В то время как вызов glViewport() выглядит так, как будто вы указываете прямоугольник внутри буфера кадра, в который вы хотите выполнить рендеринг, на самом деле вызов определяет преобразование, которое применяется как часть фиксированного функционального блока между вершинным шейдером (или геометрическим шейдером, если он у вас есть) и фрагментный шейдер. Настройки области просмотра определяют, как NDC (нормализованные координаты устройства) сопоставляются с координатами окна.

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

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

person Reto Koradi    schedule 15.11.2015