glVertexAttribPointer, чередующиеся элементы и удобство работы / кеша - PullRequest
3 голосов
/ 17 июня 2011

Итак, в процессе написания загрузчика модели для 3D-сцены, над которой я работаю, я решил упаковать вершину, текстуру и нормальные данные следующим образом:

VVVVTTTNNN

для каждойвершина, где V = координата вершины, T = координата UV и N = нормальная координата.Когда я передаю эти данные в вершинный шейдер для моей сцены, я делаю три вызова glVertexAttribPointer, например:

glVertexAttribPointer(ATTRIB_VERTEX, 4, GL_FLOAT, 0, 10, group->vertices.data);
glEnableVertexAttribArray(ATTRIB_VERTEX);

glVertexAttribPointer(ATTRIB_NORMAL, 3, GL_FLOAT, 0, 10, group->normals.data);
glEnableVertexAttribArray(ATTRIB_NORMAL);

glVertexAttribPointer(ATTRIB_UV_COORDINATES, 3, GL_FLOAT, 0, 10, group->uvcoordinates.data);
glEnableVertexAttribArray(ATTRIB_UV_COORDINATES);

Каждый из переданных указателей группы ссылается на начальную позицию в блоке данных общей вершиныгде начинается этот тип вершины:

group->vertices.data == data
group->uvcoordinates.data == &data[4]
group->normals.data == &data[7]

Одна из причин, по которой я чередовал эти данные, заключалась в программировании для удобства кэширования и минимизации данных, отправляемых на карту.(ПРИМЕЧАНИЕ. Это не относится к узким местам, связанным с реалистичной производительностью. Я занимаюсь оптимизацией, потому что хочу больше узнать о программировании для решения подобных проблем.) Однако, на мой взгляд, я не могу представить, как GL будетиметь возможность сделать вывод, что 3 разных указателя относятся к позициям смещения в одном и том же более крупном блоке данных, и, таким образом, провести необходимую оптимизацию, чтобы избежать копирования данных после того, как они уже были скопированы.Кроме того, так как я только гарантирую локальность данных в системной памяти (и на самом деле не имею никаких гарантий относительно того, как эти данные будут организованы на GPU), я действительно оптимизирую только для случая, когда я получаю доступ к любому изэти вершины вне GL.Это правильно?Являются ли эти оптимизации в основном бесполезными, или предоставление данных таким способом поможет минимизировать передачу данных в графический процессор / предотвратить ошибки кэширования при переборе данных вершин в вершинном шейдере?

1 Ответ

3 голосов
/ 17 июня 2011

OpenGL - это просто API, интеллект лежит в драйвере. В любом случае проблема на самом деле довольно проста для реализации: для каждого атрибута вершины вы получаете начальный адрес памяти, а при вызове glDrawArrays или glDrawElements ищется самый большой найденный индекс. Это определяет верхнюю границу диапазона.

Затем вы сортируете начальные адреса атрибутов вершин и для каждого адреса проверяете, перекрывает ли он диапазон с любым другим диапазоном атрибутов вершин. Вы находите смежные области и копируете их.

В случае объектов Vertex Buffer это еще проще, поскольку вы уже скопировали материал в OpenGL, готовый к обработке.

...