为了账号安全,请及时绑定邮箱和手机立即绑定

OpenGL - 索引缓冲困难

OpenGL - 索引缓冲困难

C++
慕容森 2019-08-28 15:52:42
OpenGL - 索引缓冲困难我有一个自定义文件格式,其中包含3D网格所需的所有信息(从3ds Max导出)。我已经提取了顶点,顶点索引和法线的数据。我向顶点数据,顶点索引和法线数据传递给OpenGL,我通过调用渲染网格glDrawElements(GL_TRIANGLES,...)一切看起来都很正常,但正常情况。问题是法线具有不同的指数。并且因为OpenGL只能使用一个索引缓冲区,所以它对顶点和法线都使用该索引缓冲区。如果你能建议我如何解决这个问题,我将非常感激。需要注意的重要一点是顶点/普通数据没有“排序”,因此我无法使用glDrawArrays(GL_TRIANGLES,...)- 网格无法正确渲染的功能。有没有一种方法/算法可以用来对数据进行排序,以便可以正确绘制网格glDrawArrays(GL_TRIANGLES,..)?但即使有一个算法,还有一个问题 - 我将不得不复制一些顶点(因为我的顶点缓冲区由唯一的顶点组成 - 例如,如果你有立方体我的缓冲区只有8个顶点)我不确定怎么做。
查看完整描述

3 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

对顶点和法线使用单独索引的文件类型与OpenGL顶点模型非常直接匹配。正如您所注意到的,OpenGL使用一组索引。

您需要做的是为输入中的每个唯一(顶点索引,法线索引)对创建一个OpenGL顶点。这需要一些工作,但并不是非常困难,特别是如果您使用可用的数据结构。STL map适用于此,以(顶点索引,普通索引)对作为键。我不打算提供完整的C ++代码,但我可以将其描绘出来。

假设您已经将顶点读入某种数组/矢量数据结构inVertices,其中vertexIdx存储了带索引的顶点的坐标inVertices[vertexIdx]。法线也是如此,其中normalIdx存储了具有索引的法线向量inNormals[normalIdx]

现在你可以阅读一个三角形列表,每个三角形的每个角都由a vertexIdx和a给出normalIdx。我们将构建一个combinedVertices包含顶点和法线坐标的新数组/向量,以及一个新的combinedIndices索引列表。伪代码:

nextCombinedIdx = 0indexMap = empty
loop over triangles in input file
    loop over 3 corners of triangle
        read vertexIdx and normalIdx for the corner        if indexMap.contains(key(vertexIdx, normalIdx)) then
            combinedIdx = indexMap.get(key(vertexIdx, normalIdx))
        else
            combinedIdx = nextCombinedIdx
            indexMap.add(key(vertexIdx, normalIdx), combinedIdx)
            nextCombinedIdx = nextCombinedIdx + 1
            combinedVertices.add(inVertices[vertexIdx], inNormals[normalIdx])
        end if
        combinedIndices.add(combinedIdx)
    end loop
end loop


查看完整回答
反对 回复 2019-08-28
?
千巷猫影

TA贡献1829条经验 获得超7个赞

我设法做到这一点,没有将索引缓冲区传递给OpenGL,glDrawArrays(GL_TRIANGLES,..) 我做了以下内容:填充顶点数组,顶点索引数组,法线数组和法线索引数组。然后我用排序数据创建了新的顶点和普通数组,并将它们传递给OpenGL。

for i = 0; i < vertexIndices.size(); ++i
    newVertexArray[i] = oldVertexArray[vertexIndices[i]];for i = 0; i < normalsIndices.size(); ++i
    newNormalsArray[i] = oldNormalsArray[normalsIndices[i]];

我对它进行了优化,根本没有填充索引数组。但优化取决于程序员读取网格数据的方式。


查看完整回答
反对 回复 2019-08-28
?
慕村225694

TA贡献1880条经验 获得超4个赞

嗯,是的,如果你不关心内存使用,效率和功耗,那就更简单了。在或多或少的规则网格中,顶点通常由大约6个三角形共享。根据使用索引方法的顶点缓存命中率,我希望您在GPU上创建大约3-6倍的顶点处理负载,相应的内存带宽会增加。您还将使用接近6倍的内存。考虑到使用索引构建网格只需要几行代码,我认为这绝对值得

查看完整回答
反对 回复 2019-08-28
  • 3 回答
  • 0 关注
  • 479 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信