在glDrawElements(OpenGL / VBOs)中为顶点和法线使用不同的数组

时间:2011-06-28 16:18:44

标签: opengl vbo

我目前正在OpenGL中编写.obj加载程序。我将顶点数据存储在VBO中,然后使用Vertex Attribs绑定它。法线也是如此。事实是,普通数据和顶点数据不会以相同的顺序存储。

我认为,我给glDrawElements渲染网格的索引是用OpenGL来获取顶点VBO中的顶点并在法线VBO中获得法线。

除了使用glBegin / glVertex / glNormal / glEnd告诉glDrawElements使用顶点索引和法线的其他索引之外,还有一种opengl方法吗? 感谢

3 个答案:

答案 0 :(得分:7)

没有直接的方法可以做到这一点,尽管可以通过索引到着色器内的缓冲区纹理(OpenGL 3.1功能)来模拟它。

通常不建议做这样的事情。 OBJ格式允许一次通过几个(原则上任意数量)顶点引用一个法线,因此通常要做的是构建一个“完整”顶点,包括每个顶点的坐标和法线和texcoords(复制相应的数据) )。

这确保了 a)平滑的阴影表面正确渲染
b)硬边渲染正确

(两者之间的差异只是几个顶点共享相同,相同的法线)

答案 1 :(得分:2)

您必须为位置/法线/纹理坐标等使用相同的索引。这意味着在加载.obj时,您必须插入唯一的顶点并将面指向它们。

答案 2 :(得分:2)

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