7

在尝试解析波前 .obj 文件时,我想到了两种方法:

  1. 创建一个顶点数大小的二维数组。当一个面使用一个顶点时,从数组中获取它的坐标。
  2. 获取顶点列表的起始位置,然后当面部使用顶点时,扫描线直到到达顶点。

IMO,选项 1 将非常占用内存,但速度要快得多。由于选项 2 涉及大量文件读取,(并且因为大多数对象中的顶点数量变得非常大),这将慢得多,但内存密集度较低。

问题是:比较内存和速度之间的权衡,哪个选项更适合普通计算机?而且,有没有替代的方法?

我计划使用 OpenGL 和 GLFW 来渲染对象。

4

5 回答 5

6

IMO,选项 1 将非常占用内存,但要快得多。

无论如何,您必须将这些顶点放入内存。但是不需要二维数组,顺便说一句,这会导致两个指针间接,从而对性能造成重大影响。只需std::vector<Vertex>对您的数据使用一个简单的,矢量索引就是随附人脸列表的索引。

编辑由于评论

class Vertex
{
    union { struct { float x, y, z }; float pos[3] };
    union { struct { float nx, ny, nz }; float normal[3] };
    union { struct { float s, t }; float pos[2] };
    Vertex &operator=();
}

std::vector<Vertex>;
于 2011-10-17T15:57:11.130 回答
4

通常,您将顶点列表读入数组。解析 ASCII 文本非常慢;加载文件时只执行一次,然后将所有内容存储在内存中的数组中。

三角形/面也是如此。每个三角形通常由三个顶点索引的列表组成。这也应该存储在一个数组中。

您可能会发现 VTK 开源库中的 OBJ 阅读器很有用: http ://www.vtk.org/doc/nightly/html/classvtkOBJReader.html 。我们使用它并且没有理由自己编写...直接使用VTK,或者您可能会发现学习源代码对您自己的读者有进一步的启发很有好处。

在我看来,OBJ 文件的主要缺点之一是使用 ASCII。由于字符串解析,如果 3D ASCII 文件(无论是 STL、PLY、OBJ 等)是 ASCII,则加载速度非常慢。二进制格式文件要快得多,如果性能是一个问题,则应始终使用:良好二进制格式的加载时间是瞬时的。

于 2011-10-17T15:41:21.353 回答
2

只需将它们加载到数组中。内存应该不是问题。您的系统(通常)拥有比 GPU 更多的内存。如果您遇到内存问题,您可能正在加载一个过于详细的模型。(我半假设您将在 OpenGL 中制作游戏。如果您对如此大的模型文件有特殊需求,您仍然需要找到一种方法来加载适当的块。)

于 2011-10-17T16:42:56.673 回答
0

你不应该需要一个二维数组。你的模型应该是三角测量的,然后你可以简单地使用 gluts obj loader 加载 obj 文件。只需将点、面和法线存储在 3 个单独的数组/缓冲区中。这里有一个例子,但是如果你想快速做到这一点,你应该选择二进制格式。

于 2011-10-17T15:44:39.837 回答
0

这是一个相当不错的原型设计解决方案,运行一个脚本来生成用于 OpenGL 或您首选的渲染 API 的数组。obj2opengl.pl 是一个 perl 脚本,你需要安装 perl,你可以在这里找到。GitHub 链接在这里

运行 perl 脚本时,您可能会在第 154 行遇到运行时错误,涉及if(defined(@center)). 将其替换为if(@center)

从示例中,一旦使用数据生成头文件,您就可以使用它,如下所示:

/*
created with obj2opengl.pl

source file    : ./banana.obj
vertices       : 4032
faces          : 8056
normals        : 4032
texture coords : 4420


// include generated arrays
#import "./banana.h"

// set input data to arrays
glVertexPointer(3, GL_FLOAT, 0, bananaVerts);
glNormalPointer(GL_FLOAT, 0, bananaNormals);
glTexCoordPointer(2, GL_FLOAT, 0, bananaTexCoords);

// draw data
glDrawArrays(GL_TRIANGLES, 0, bananaNumVerts);
*/
于 2015-08-25T22:09:20.150 回答