【问题标题】:Using a different array for vertices and normals in glDrawElements (OpenGL/VBOs)在 glDrawElements (OpenGL/VBO) 中为顶点和法线使用不同的数组
【发布时间】:2011-09-24 11:31:38
【问题描述】:

我目前正在用 OpenGL 编写一个 .obj 加载器。我将顶点数据存储在 VBO 中,然后使用 Vertex Attribs 绑定它。法线也一样。问题是,法线数据和顶点数据的存储顺序不同。

我想,OpenGL 使用我给 glDrawElements 来渲染网格的索引来获取顶点 VBO 中的顶点并获取法线 VBO 中的法线。

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

【问题讨论】:

    标签: opengl vbo


    【解决方案1】:

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

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

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

    (两者的区别只是几个顶点共享相同,相同的法线)

    【讨论】:

    • 请注意,当我说“不可取”时,我是认真的。不仅逻辑比构建适当的顶点流并上传一次要复杂得多,而且它意味着随机而不是顺序数据访问,即每个顶点上或多或少都会保证缓存未命中。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      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
      

      【讨论】:

        猜你喜欢
        • 2023-03-05
        • 1970-01-01
        • 2012-05-27
        • 2020-12-16
        • 1970-01-01
        • 2012-07-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多