Как re-glBufferData () взаимодействует с glVertexAttribPointer?
Я понимаю базовую последовательность: 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) для индекса индекса .
Когда указан универсальный массив атрибутов вершин, размер , тип , нормализация , шаг и указатель сохраняются как состояние массива вершин в дополнение к привязке текущего объекта буфера массива вершин.
Кажется, что и байтовое смещение, и привязка объекта буфера могут оставаться действительными, даже если хранилище данных было заменено чем-то другим. Но я также мог видеть, что это реализовано так, что во время вызова привязка фиксирует определенный указатель в хранилище данных, который становится недействительным, если хранилище данных заменяется. Формулировка, похоже, не исключает ни того, ни другого.
Ответы
Похоже, что привязки 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 ().