Привязка к GL_ELEMENT_ARRAY_BUFFER без привязки к VAO

Буфер, в настоящее время связанный с GL_ELEMENT_ARRAY_BUFFER target в OpenGL является частью состояния, содержащегося в объекте Vertex Array (далее VAO). В соответствии со спецификацией профиля ядра OpenGL 4.4 может показаться, что попытка изменить или получить доступ к GL_ELEMENT_ARRAY_BUFFER в то время как никакой VAO не связан, ошибка:

10.4. Объекты Vertex Array

INVALID_OPERATION ошибка генерируется любыми командами, которые
изменять, рисовать или запрашивать состояние массива вершин, когда нет массива вершин
связан. Это происходит в начальном состоянии GL и может происходить как
Результат BindVertexArray или побочный эффект DeleteVertexArrays.

Это поддерживается вики OpenGL Буферный объект страница:

GL_ELEMENT_ARRAY_BUFFER​

Все функции рендеринга формы gl*Draw*Elements*​ будет использовать указатель
поле в виде байтового смещения от начала объекта буфера, привязанного к этому
цель. Индексы, используемые для индексированного рендеринга, будут взяты из буфера
объект. Обратите внимание, что эта цель привязки является частью состояния объектов Vertex Array,
так что ВАО должен быть связанным перед связыванием буфера здесь.

Теперь было бы хорошо, если бы это было не так. Это позволит легко создавать и управлять индексными буферами отдельно от любого конкретного VAO. Но если просто привязать буфер к GL_ELEMENT_ARRAY_BUFFER verboten, когда нет привязки к VAO, единственная альтернатива для класса, представляющего буфер индекса, для привязки фиктивного VAO при их создании / обновлении / и т.д.

Николь Болас отлично OpenGL учебник говорит, что этот тип использования действительно действителен:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER): Вызов этого без привязки к VAO не подведет.

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

2

Решение

Если у вас есть AMD или NV GPU, вы всегда можете использовать EXT_direct_state_access расширение для манипулирования буферным объектом без его привязки (это чисто драйверная функция и не требует какого-либо специального класса оборудования). К сожалению, Intel, Mesa и Apple не удосужились реализовать это расширение, несмотря на его 5-летнее существование — ленивые бездельники.


Посмотрите на следующие функции, они значительно облегчат то, что вы описываете:

  • glNamedBufferDataEXT (...)
  • glNamedBufferSubDataEXT (...)
  • glMapNamedBufferEXT (...)
  • glUnmapNamedBufferEXT (...)

Теперь, поскольку адаптация DSA редка, вам, вероятно, придется написать запасной код для систем, которые его не поддерживают. Вы можете воспроизвести функциональные возможности DSA, написав функции с идентичными сигнатурами функций, которые используют фиктивные VAO для привязки VBO и IBO для манипулирования данными в системах, которые не поддерживают расширение. Вы должны будете отследить, что было связано с VAO, прежде чем использовать его, и восстановить его до того, как упомянутая функция вернется, чтобы устранить побочные эффекты.

В хорошем движке вы должны скрывать состояние привязки VAO, а не запрашивать его у GL. То есть вместо использования glBindVertexArray (...) непосредственно вы реализуете систему, которая упаковывает этот вызов и поэтому всегда знает, что VAO связано с конкретным контекстом. В конце концов, это делает эмуляцию функциональности DSA там, где не поддерживается драйвер много более эффективным. Если вы пытаетесь что-то подобное, вы должны знать, что glDelete (...) функции неявно отменяют привязку (путем связывания 0) удаляемый объект, если он связан в текущем контексте.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]