将顶点数组和面索引加载到OpenGL-ES中的最快方法?
Posted
技术标签:
【中文标题】将顶点数组和面索引加载到OpenGL-ES中的最快方法?【英文标题】:Fastest way to load arrays of vertices and face indices into OpenGL-ES? 【发布时间】:2011-05-18 17:21:49 【问题描述】:我正在尝试加载已格式化的 .obj 文件:
vertexX vertexY vertexZ normalX normalY normalZ
和:
index1 index2 index3
格式化成向量和向量数组,然后我直接在 Opengl-ES 中渲染。我的问题是,当我尝试将模型加载到数组中时,加载它们大约需要 40 秒。我不知道为什么它会这么慢,我已经看到其他代码只加载了几个相同的模型秒。有什么建议?我加载文件的代码如下:
-(void)loadModel:(NSString*)filePath
try
ifstream objFile([filePath UTF8String]);
objFile >> numVertices;
objFile.ignore(128, '\n');
vertices.resize(numVertices*6);
VertexNormal* vertex = (VertexNormal*) &vertices[0];
svec3* faceDef;
while (objFile)
char c = objFile.get();
switch (c)
case 'v':
objFile >> vertex->vertices.x >> vertex->vertices.y >> vertex->vertices.z
>> vertex->normals.x >> vertex->normals.y >> vertex->normals.z;
vertex++;
break;
case 'f':
objFile >> faceDef->x >> faceDef->y >> faceDef->z;
faceDef++;
break;
case '#':
part newPart;
partList.push_back(newPart);
numObjects++;
objFile.ignore(128, '\n');
int numFaces;
objFile >> numFaces;
partList[partList.size()-1].faces.resize(numFaces*3);
partList[partList.size()-1].numFaces = numFaces;
faceDef = (svec3*) &partList[partList.size()-1].faces[0];
break;
default:
break;
objFile.ignore(128, '\n');
objFile.close();
free(objFile);
catch (NSException *ex)
NSLog(@"%@", [ex reason]);
我的一个想法是将数组序列化为二进制文件,然后将它们直接反序列化到我的程序中。虽然还没有想出如何做到这一点,但也许这些方面的东西可能是一个解决方案。
【问题讨论】:
【参考方案1】:游戏行业的最佳做法是将所有模型数据保存为二进制格式,这样您就可以非常快速地加载可以表示为顶点、法线或其他任何内容的整个非交错内存块。您所需要的一切 - 制作用于将文本 .obj 文件转换为您自己的二进制文件的小型命令行工具。
还有:
您是否尝试使用 stdio 库而不是 stl ifstream 进行文本加载? 也许尝试一次读取所有文本数据并从内存中填充数组,而不是从文件系统中? 文件中有多少部分?每次调整 std::vector 的大小都会导致新的分配和复制。如果您之前知道所需的卷,请尝试在 std::vector 中保留空间。【讨论】:
很好的建议。我最终在 PC 上编写了自己的二进制格式。尚未在 iPad 上进行测试,但 PC 上的加载时间从 33 秒变为 1 秒,文件大小从 17MB 变为 7MB 未压缩,3MB 变为 1.8MB 压缩。好多了。谢谢。 @Davido 你能告诉我如何编写自己的二进制格式吗? “33 秒到 1 秒”简直太棒了。【参考方案2】:我不知道您是否考虑过这一点,但如果您的 .obj 文件不会在您的应用程序中更改,您可以将它们格式化为 Objective-C 数组并直接使用您的代码编译它们。
【讨论】:
我以前从未这样做过,您有代码示例说明如何做到这一点吗?听起来这可能是我正在寻找的。span> 对不起,我忘了澄清。这可能会改变您的建议,但我希望用户能够从他们的设备打开新的 .obj 文件并在我的 OpenGL 查看器中查看这些文件。所以静态文件是行不通的,除非有办法基本上将数组的代码放在文本文件中,并让 Objective-c 在运行时直接编译这些数组。 @Davido 抱歉,我对 Objective-C 没有任何经验。这只是一个建议。以上是关于将顶点数组和面索引加载到OpenGL-ES中的最快方法?的主要内容,如果未能解决你的问题,请参考以下文章
OrientDB GraphDatabase:@RID 的 OSQLSynchQuery 以获取 graph.getVertex(rid) ...从索引键加载顶点的最快方法?