Как re-glBufferData () взаимодействует с glVertexAttribPointer?

Aug 21 2020

Я понимаю базовую последовательность: glGenBuffers () создает «имя буферного объекта», glBindBuffer () создает фактический буферный объект (а также связывает имя), glBufferData () «создает и инициализирует хранилище данных буферного объекта» и glVertexAttribPointer () устанавливает формат данных буфера, а также сохраняет привязку объекта буфера как часть состояния массива атрибутов вершин.

Сложность, в которой я не уверен, заключается в том, что материал glVertexAttribPointer () остается действующим, если «хранилище данных буферного объекта» (но не сам буферный объект) сдувается новым вызовом glBufferData (). Я знаю, что это обычно не очень хорошая идея - используйте glBufferSubData (), когда просто переписываете буферы, - но glBufferData () кажется единственным вариантом, если его размер нужно изменить. К тому же мне просто любопытно.

Справочные страницы говорят о том, что все может пойти по другому пути - в частности (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttribPointer.xhtml):

Если указатель не равен NULL, ненулевой именованный буферный объект должен быть привязан к цели GL_ARRAY_BUFFER (см. GlBindBuffer ), в противном случае генерируется ошибка. указатель рассматривается как смещение байта в хранилище данных буферного объекта. Привязка буферного объекта (GL_ARRAY_BUFFER_BINDING) сохраняется как общее состояние массива атрибутов вершин (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) для индекса индекса .

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

Кажется, что и байтовое смещение, и привязка объекта буфера могут оставаться действительными, даже если хранилище данных было заменено чем-то другим. Но я также мог видеть, что это реализовано так, что во время вызова привязка фиксирует определенный указатель в хранилище данных, который становится недействительным, если хранилище данных заменяется. Формулировка, похоже, не исключает ни того, ни другого.

Ответы

D0SBoots Aug 22 2020 at 04:45

Похоже, что привязки glVertexAttribPointer () остаются действительными даже после последующих вызовов glBufferData (). Я определил это, попробовав, что не является стопроцентным доказательством - он может работать только в этой реализации (в моем случае драйверы NVidia).

Однако с обратным вызовом сообщения об ошибке и включенным режимом отладки я получаю следующее сообщение при втором вызове glBufferData (), которое убедительно указывает на то, что эта ситуация ожидается / предназначена для:

[LWJGL] Сообщение отладки OpenGL
    ID: 0x20071
    Источник: API
    Тип: ДРУГИЕ
    Серьезность: УВЕДОМЛЕНИЕ
    Сообщение: Подробная информация о буфере: Буферный объект 1 (привязанный к GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1) и GL_ARRAY_BUFFER_ARB, в качестве источника буфера будет использоваться память объекта в качестве источника памяти для VICTEX_DRAWAT, подсказка для использования будет использоваться как объект памяти GLIDE_STAT).

Первые две привязки представляют два моих вызова glVertexAttribPointer () и отсутствуют в сообщении, которое регистрируется при первом вызове glBufferData ().