将顶点数组和面索引加载到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) ...从索引键加载顶点的最快方法?

将大量 .data 加载到数组中的最快方法

Opengl 顶点数组对象

从 MySQL 将数值数据加载到 python/pandas/numpy 数组中的最快方法

将大型 CSV 文件加载到核心数据中的最快方法是啥

查找哪些三角形共享一个顶点的最快算法