Использование другого массива для вершин и нормалей в glDrawElements (OpenGL / VBOs) - PullRequest
7 голосов
/ 28 июня 2011

Я сейчас программирую загрузчик .obj в OpenGL. Я храню данные вершин в VBO, а затем связываю их с помощью Vertex Attribs. То же самое для нормалей. Дело в том, что нормальные данные и данные вершин не хранятся в одном и том же порядке.

Индексы, которые я даю glDrawElements для визуализации меша, я полагаю, используются OpenGL для получения вершин в вершине VBO и для получения нормалей в нормалях VBO.

Есть ли способ opengl, кроме использования glBegin / glVertex / glNormal / glEnd для указания glDrawElements использовать индекс для вершин и другой индекс для нормалей? Спасибо

Ответы [ 3 ]

7 голосов
/ 28 июня 2011

Прямого способа сделать это не существует, хотя вы могли бы смоделировать его путем индексации в буферную текстуру (функция OpenGL 3.1) внутри шейдера.

Как правило, не рекомендуетсясделай такую ​​вещь, хотя.Формат OBJ позволяет одновременно ссылаться на одну нормаль несколькими (в принципе, любым числом) вершинами, поэтому обычно нужно создать «полную» вершину, включающую в себя координаты, нормаль и текстовые координаты для каждой вершины (дублируя соответствующие данные).

Это гарантирует, что
a) сглаженные затененные поверхности будут правильно отображаться
b) жесткие края будут отображаться правильно

(разница между двумя заключается в том, что только несколько вершин имеют одинаковыеидентично нормальному)

2 голосов
/ 29 июня 2011

OpenGL обрабатывает вершину как один длинный вектор

(position, normal, texcoord[0]…texcoord[n], attrib[0]…attrib[n])

, и эти длинные векторы индексируются.Ваш вопрос относится к той же категории, например, как использовать общие вершины с несколькими нормалями.И канонический ответ заключается в том, что эти вершины на самом деле не являются общими, потому что в долгосрочной перспективе они не идентичны."вершины, добавляющие их в (новый) список с ограничением уникальности;(хеш) карта из вершины → индекс служит этой работе.Как то так

next_uniq_index = 0
for f in faces:
    for i in f.indices:
        vpos = vertices[i.vertex]
        norm = normals[i.normal]
        texc = texcoords[i.texcoord]
        vert = tuple(vpos, norm, texc)
        key
        if uniq_vertices.has_key(key):
             uniq_faces_indices.append(uniq_vertices[key].index)
        else:
             uniq_vertices[key] = {vertex = key, index = next_uniq_index}
             next_uniq_index = next_uniq_index + 1
2 голосов
/ 28 июня 2011

Вы должны использовать один и тот же индекс для позиции / нормалей / текстурных координат и т. Д. Это означает, что при загрузке .obj вы должны вставить уникальные вершины и указать на них свои лица.

...