我有一个定制的文件格式,它有一个3D网格所需的所有信息(从3ds Max导出)。我提取了顶点,顶点指数和法线的数据。
我将顶点数据、顶点索引和法线数据传递给OpenGL,并通过调用glDrawElements(GL_TRIANGLES,...)
呈现网格。
一切看上去都是正常的除了正常值。问题是法线有不同的指数。因为OpenGL只能使用一个索引缓冲区,所以它对顶点和法线都使用该索引缓冲区。
如果你能建议我如何解决这个问题,我将非常感激。
需要注意的是,顶点/法线数据没有“排序”,因此我无法使用glDrawArrays(GL_TRIANGLES,...)
的功能--网格不能正确呈现。
是否有一种方法/算法可以用来对数据进行排序,以便用glDrawArrays(GL_TRIANGLES,..)
正确绘制网格?但是,即使有一个算法,还有一个问题--我将不得不复制一些顶点(因为我的顶点缓冲区由唯一的顶点组成--例如,如果您有多维数据集,我的缓冲区将只有8个顶点),而我不知道如何做到这一点。
发布于 2014-05-01 04:28:33
我成功地做到了这一点,而没有用glDrawArrays(GL_TRIANGLES,..)
将索引缓冲区传递给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]];
我对它进行了一些优化,根本没有填充索引数组。但是优化取决于程序员读取网格数据的方式。
发布于 2014-04-28 22:04:52
对顶点和法线使用单独索引的文件类型与OpenGL顶点模型不完全匹配。正如您注意到的,OpenGL使用一组索引。
您需要做的是为输入中的每个唯一(顶点索引、普通索引)对创建一个OpenGL顶点。这需要做一些工作,但并不困难,特别是在使用可用数据结构的情况下。一个STL map
可以很好地工作,以(顶点索引,普通索引)对作为键。我不打算提供完整的C++代码,但我可以把它勾勒出来。
假设您已经将顶点读入某种数组/向量数据结构inVertices
中,其中索引vertexIdx
的顶点坐标存储在inVertices[vertexIdx]
中。法线也是如此,其中带索引normalIdx
的法线向量存储在inNormals[normalIdx]
中。
现在,您可以读取一个三角形列表,每个三角形的每个角都由一个vertexIdx
和一个normalIdx
给出。我们将构建一个包含顶点和法线坐标的新combinedVertices
数组/向量,以及一个新的combinedIndices
索引列表。伪码:
nextCombinedIdx = 0
indexMap = 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
https://stackoverflow.com/questions/23349080
复制相似问题