Использовать один GL ELEMENT_ARRAY_BUFFER для ссылки на каждый атрибут из 0?

OpenGL 4.4, C ++ 11

Имею ли я право использовать индексы в element_array_buffer от 0 для каждого атрибута, устанавливая атрибуты вершин для element_array_buffer и array_buffer?

Расположение данных

VAO
Buffer(array_buffer)
PositionFloat * n
TextureFloat  * n
NormalFloat   * n
Buffer(element_array_buffer)
PositionIndex * 1
TextureIndex  * 1
NormalIndex   * 1

Использование данных

//gen
glBindVertexArray(VAO);

glBindBuffer(array_buffer, vbo);
glBufferData(array_buffer, size(vertices), data(vertices), access(vertices));
glVertexAttribPointer(POSITIONS, 3, float, offset(0));
glVertexAttribPointer(UVS,       2, float, offset(positions));
glVertexAttribPointer(NORMALS,   3, float, offset(normals));

glBindBuffer(element_array_buffer, ebo);
glBufferData(element_array_buffer, size(elements), data(elements), access(elements));
...?! /*Cannot set element attributes!
If I could, I would set a strided, offset attribPointer for each attribute,
so that if 0 appears in the NORMALS attribute, it will look up the first normal,
and not the first element in the buffer. */

Я пишу свои индексы так, чтобы я мог ссылаться на первую вершину, UV и Normal с 0/0/0. Можно ли отобразить это в element_array_buffer и использовать его как таковой? Или мое решение добавить nPositions к моим индексам текстуры, а nPositions + nTextures к моим нормальным индексам?

0

Решение

OpenGL не поддерживает отдельные индексы для каждого атрибута вершины. При использовании буферов для ваших атрибутов вершин вам необходимо создать вершину для каждой уникальной комбинации атрибутов вершин.

Каноническим примером является куб с позициями и нормалями в качестве атрибутов вершин. Куб имеет 8 углов, поэтому он имеет восемь различных значений для атрибута позиции. У него 6 сторон, поэтому у него есть 6 различных значений для нормального атрибута. Сколько вершин у куба? В OpenGL ответ … 24.

Есть как минимум два способа определить, почему число вершин в этом случае равно 24:

  • Куб имеет 6 сторон. Мы не можем делить вершины между сторонами, потому что они имеют разные нормали. У каждой стороны есть 4 угла, поэтому нам нужно 4 вершины с каждой стороны. 6 * 4 = 24.
  • Куб имеет 8 углов. На каждом из этих 8 углов встречаются 3 стороны. Поскольку эти 3 стороны имеют разные нормали, нам нужна отдельная вершина для каждой из них. 8 * 3 = 24.

Теперь, поскольку вы специально спрашиваете об OpenGL 4.4, есть другие варианты, которые можно рассмотреть. Например, вы можете указать значения ваших атрибутов вершин, которые будут индексами, а не координатами. Поскольку вы, конечно, можете использовать несколько атрибутов вершины, вы можете иметь несколько индексов для каждой вершины. Затем ваш вершинный шейдер получает эти индексы как значения атрибутов вершин. Затем он может получить фактические значения атрибутов из другого источника. Возможности для этих источников включают в себя:

  • Однородные буферы.
  • Текстурные буферы.
  • Текстуры.

Я не уверен, что что-то из этого будет таким же эффективным, как простое использование атрибутов вершин более традиционным способом. Но может быть стоит попробовать, если вы хотите изучить все ваши варианты.

Экземплярный рендеринг — это еще один метод, который иногда помогает визуализировать различные комбинации атрибутов вершин, не перечисляя все комбинации. Но это действительно работает, только если ваша геометрия повторяется. Например, если вы хотите визуализировать множество кубов одним вызовом отрисовки и использовать разные цвета для каждого из них, экземплярный рендеринг будет работать отлично.

2

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


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