Связь между расположением атрибута X и объектом буфера, который предоставляет этот атрибут, создается с помощью команды glVertexAttribPointer
. Как это работает, просто, но не интуитивно понятно.
В то время, когда glVertexAttribPointer
называется (это та часть, которую многие люди не получают), любой объект буфера, связанный в данный момент с GL_ARRAY_BUFFER
, становится связанным с атрибутом X, где X это первый параметр glVertexAttribPointer
.
Итак, если вы хотите иметь атрибут, который приходит из одного буфера, и атрибут, который приходит из другого, вы делаете это:
glEnableVertexAttrib(position_location);
glEnableVertexAttrib(color_location);
glBindBuffer(GL_ARRAY_BUFFER, buffPosition);
glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, buffColor);
glVertexAttribPointer(color_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
Что касается того, следует ли разделять атрибуты на разные буферы ... Я бы сказал, что вы должны делать это только в том случае, если у вас есть очевидная потребность .
Например, допустим, вы создаете динамическую карту высот, возможно, для какого-то эффекта воды. Положение Z каждого элемента изменяется, но это также означает, что нормали изменяются. Однако положения XY и координаты текстуры не меняются.
Эффективная потоковая передача часто требует либо двойной буферизации объектов буфера, либо их аннулирования (перераспределение их с помощью glBufferData (NULL) или glMapBufferRange (GL_INVALIDATE_BIT)). Любой способ работает только в том случае, если потоковые данные находятся в другом объекте буфера из непоточных данных.
Еще один пример очевидной необходимости - это проблема памяти и несколько объектов имеют общие списки атрибутов. Возможно, объекты имеют разные позиции и нормальные массивы, но одинаковые цветовые и текстурные координатные массивы. Или что-то в этом роде.
Но в противном случае лучше всего поместить все объекты в один буфер. Даже если вы не чередуете массивы.