Хранение разных атрибутов вершин в разных VBO - PullRequest
8 голосов
/ 29 августа 2011

Можно ли хранить разные атрибуты вершин в разных вершинных буферах?

Все примеры, которые я видел до сих пор, делают что-то подобноекак это:

glBindBuffer(GL_ARRAY_BUFFER, buffname);
glEnableVertexAttrib(position_location);
glEnableVertexAttrib(color_location);
glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(color_location, 3, GL_FLOAT, GL_FALSE, 0, (void*)(3*n));

glDrawArrays(GL_TRIANGLES, 0, n/3);

glDisableVertexAttrib(position_location);
glDisableVertexAttrib(color_location);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Разве нельзя хранить данные о местоположении и данные о цвете в разных VBO?Проблема в том, что я не понимаю, как это сработает, потому что вы не можете связать два буфера одновременно, не так ли?

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

Чтобы уточнить: Я понимаю, как я мог хранить различные атрибутыв разных VBO.Я не понимаю, как бы я их потом нарисовал.

1 Ответ

10 голосов
/ 29 августа 2011

Связь между расположением атрибута 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)). Любой способ работает только в том случае, если потоковые данные находятся в другом объекте буфера из непоточных данных.

Еще один пример очевидной необходимости - это проблема памяти и несколько объектов имеют общие списки атрибутов. Возможно, объекты имеют разные позиции и нормальные массивы, но одинаковые цветовые и текстурные координатные массивы. Или что-то в этом роде.

Но в противном случае лучше всего поместить все объекты в один буфер. Даже если вы не чередуете массивы.

...