猿问

OpenGL - 索引缓冲困难

OpenGL - 索引缓冲困难

我有一个自定义文件格式,其中包含3D网格所需的所有信息(从3ds Max导出)。我已经提取了顶点,顶点索引和法线的数据。

我向顶点数据,顶点索引和法线数据传递给OpenGL,我通过调用渲染网格glDrawElements(GL_TRIANGLES,...)

一切看起来都很正常,但正常情况。问题是法线具有不同的指数。并且因为OpenGL只能使用一个索引缓冲区,所以它对顶点和法线都使用该索引缓冲区。

如果你能建议我如何解决这个问题,我将非常感激。

需要注意的重要一点是顶点/普通数据没有“排序”,因此我无法使用glDrawArrays(GL_TRIANGLES,...)- 网格无法正确渲染的功能。

有没有一种方法/算法可以用来对数据进行排序,以便可以正确绘制网格glDrawArrays(GL_TRIANGLES,..)?但即使有一个算法,还有一个问题 - 我将不得不复制一些顶点(因为我的顶点缓冲区由唯一的顶点组成 - 例如,如果你有立方体我的缓冲区只有8个顶点)我不确定怎么做。


慕容森
浏览 481回答 3
3回答

忽然笑

对顶点和法线使用单独索引的文件类型与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

千巷猫影

我设法做到这一点,没有将索引缓冲区传递给OpenGL,glDrawArrays(GL_TRIANGLES,..)&nbsp;我做了以下内容:填充顶点数组,顶点索引数组,法线数组和法线索引数组。然后我用排序数据创建了新的顶点和普通数组,并将它们传递给OpenGL。for&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;vertexIndices.size();&nbsp;++i &nbsp;&nbsp;&nbsp;&nbsp;newVertexArray[i]&nbsp;=&nbsp;oldVertexArray[vertexIndices[i]];for&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;normalsIndices.size();&nbsp;++i &nbsp;&nbsp;&nbsp;&nbsp;newNormalsArray[i]&nbsp;=&nbsp;oldNormalsArray[normalsIndices[i]];我对它进行了优化,根本没有填充索引数组。但优化取决于程序员读取网格数据的方式。

慕村225694

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