Мне было интересно, какое состояние хранится в OpenGL VAO. Я понял, что VAO содержит состояние, связанное со спецификациями вершин буферизованных вершин (какие атрибуты находятся в буферах и какие буферы связаны, ...). Чтобы лучше понять правильное использование VAO, я бы хотел точно знать, в каком состоянии они находятся.
Как я предполагаю, что VAO следует использовать
Из простых примеров я понял, что правильное использование VAO заключается в следующем:
Настроить
Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO
оказание
Bind VAO
---- Draw
Unbind VAO
Исходя из этого, я предполагаю, что по крайней мере привязки буфера вершин и спецификации атрибутов вершин хранятся в VAO. Однако я не уверен, как этот шаблон использования распространяется на ситуации, когда (несколько) текстур и (несколько) шейдерных программ вступают в игру. Сохраняется ли активная шейдерная программа в VAO? И хранятся ли в VAO привязки текстур (с их настройками выборки / обтекания )? То же самое для униформы ?
Поэтому мои вопросы таковы:
- Какое точное состояние хранится в OpenGL VAO ? (Привязки VBO, спецификации атрибутов, активная программа шейдеров, привязки текстур, настройки выборки / обтекания текстур, униформа ...?)
- Как правильно использовать VAO в более сложной настройке рендеринга, в которой участвуют (несколько) текстур с соответствующими настройками выборки / обтекания, (несколько) шейдерных программ и униформ?
Ответы:
VAO хранит данные о расположении атрибутов вершин. (И некоторые другие данные, связанные с ними.)
"VBO bindings, active shader program, texture bindings, texture sampling/wrapping settings, uniforms"
Совершенно не связаны с ним.Вы можете спросить, почему он не помнит привязку VBO. Поскольку вам не нужно связывать VBO для рисования чего-либо, вам нужно только связать это при создании VAO: когда вы звоните
glVertexAttribPointer(...)
, VAO вспоминает, что VBO в настоящее время связано. И VAO будет брать атрибуты из этих VBO, когда вы их рисуете, даже если эти VBO в настоящее время не связаны.Кроме того, VAO и VBO должны использоваться по-разному:
Это не будет работать
потому что вам нужно связать VBO, чтобы указать расположение атрибутов.
Итак, вы должны сделать это так:
Вы можете изменить данные VBO, когда захотите, но вы должны связать их раньше.
И рисунок должен выглядеть так:
Как вы могли заметить, я удалил
unbind
звонки из ваших списков. Они почти полностью бесполезны и немного замедляют вашу программу, поэтому я не вижу причин для их вызова.источник
gl{Enable|Disable}VertexAttribArray()
), их значения по умолчанию (glVertexAttrib*()
), режим их создания (glVertexAttribDivisor()
) и, возможно, что-то еще.Он хранит только привязку вершин и привязку индексного буфера
Это все параметры
glVertexAttribPointer
плюс буфер, связанный с Vertex_Array_buffer во время вызоваglVertexAttribPointer
и связанный Element_Array_buffer.Униформа является частью текущей программы.
Все остальное - глобальное состояние.
В случае сомнений вы можете проверить таблицы состояний в спецификации используемой версии.
источник
Вот простое, но эффективное объяснение, в основном объект буфера имеет информацию, которую можно интерпретировать как просто биты необработанных данных, которые сами по себе ничего не значат, так что это ТОЧНО данные, которые действительно могут быть просмотрены любым способом
и способ, которым OpenGL был разработан для работы, заключается в том, что вы должны ОПРЕДЕЛИТЬ, как будут выглядеть данные, передаваемые вами в различные шейдеры.
в том, что вы также должны определить, как они будут читать эти данные, в каком формате, и что делать с ними, как они будут использоваться и для чего, вся эта информация хранится в VAO
например, вы можете объявить данные, которые хранятся в массиве, как это
float vbo = {11.0,2.0,3.0,4.0}
то, что требуется затем на этом этапе, - это как интерпретировать эти данные из VBO в VAO, и что это означает следующим образом
VAO может быть установлен, чтобы читать 2 числа с плавающей точкой на вершину (что сделало бы это 2 векторами с двумя измерениями x, y), или вы можете сказать vao интерпретировать это как 1 вектор с 4 измерениями, то есть x, y, z, w и т. д.
но также другие атрибуты этих данных определяются и хранятся в VAO, такие как формат данных (несмотря на то, что вы объявили массив с плавающей точкой, вы можете указать шейдеру, что он будет считываться как целое число, и, конечно, система преобразует необработанные данные в процесс от числа с плавающей точкой до целого числа и имеет свой собственный набор правил, что делать в таких условиях)
Таким образом, в основном VBO - это данные, а VAO хранит, как интерпретировать эти данные, потому что шейдеры и сервер OpenGL спроектированы так, чтобы быть очень любопытными и должны знать все, прежде чем решат, как их обрабатывать, что с ними делать и где. поставить это
конечно, он не очень любопытный, он действительно выглядит наиболее эффективным, потому что ему нужно хранить эти данные в памяти графического сервера, чтобы он получал наиболее эффективную и быструю обработку (если он не решит, что ему не нужно делать это, если данные не должны обрабатываться таким образом и использоваться для некоторой другой информации, к которой часто не обращаются), и, следовательно, почему детали того, что делать с данными и как обрабатывать их, должны храниться в VAO, поэтому VAO похож на заголовок, а VBO - на чистые необработанные данные, которые заголовок использует и определяет (в этом случае передает атрибуты вершины шейдера), за исключением того, что VBO не ограничивается использованием только одной VAO. могут быть использованы и использованы повторно и связаны со многими VAO, например:
то, что вы можете сделать, это то, что вы можете привязать один буферный объект к VAO1, а также (отдельно) привязать один и тот же буферный объект к VAO2, причем каждый интерпретирует его по-разному, так что если ваш шейдер должен обрабатывать данные, в зависимости от того, какой VAO является тем, который является При связывании он будет обрабатывать одни и те же необработанные данные по-разному для мошенника (рисование пикселей в окне), что приведет к различному отображению одних и тех же данных, что будет зависеть от того, как вы определили их использование в VAO
источник