3

我想将 obj 模型导入我的 opengl 程序。我有一个类/数据格式,用于将属性数据传递到着色器:

class CustomVertex : public IVtxFmt
{
public:
  float m_Position[3];      // x, y, z      offset 0, size = 3*sizeof(float)    
  float m_Normal[3];        // nx, ny, nz;  offset 3
  float m_TexCoords[2];     // u, v         offset 6
  float m_Colour[4];        // r, g, b, a   offset 8
  float m_Tangent[3];       // r, g, b      offset 12
  float m_Bitangent[3];     // r, g, b      offset 15
};

因此,我正在使用从 Internet 下载的小木屋模型。

小木屋有几个顶点、法线和纹理坐标定义,后面是面定义列表。

所以我的第一个直觉是解析 obj 文件并最终得到

vector<vertex>
vector<Normal>
vector<TexCoord>

将其转换为我的 CustomVertex 格式并不简单,因为文件中可能定义了 210 个顶点、100 个 tex 坐标和 80 个法线。

在以这种格式列出约 390 个面孔之后:

f 83/42/1 67/46/1 210/42/1 

我在文件中遇到以下内容:

#
# object tile00
#

其次是更多的顶点定义。

因此,据此,我推断一个模型可能由几个子对象组成,每个子对象由多个面定义;每个面由 3 x vertex / normal / texcoord 索引值定义。

因此,为了获得 CustomVertex 的向量,我认为我需要执行以下操作:

创建和填充:

vector <vertex>
vector <normal>
vector <texcoord>

vector <indices>

我需要为面部定义中的每个唯一的 v/vn/vt 三元组创建一个 CustomVertex。

所以我想到了创建一个地图:

std::vector<CustomVertex> and
std::map< nHashId, CustomVertex_index >

所以我的想法是,对于我遇到的每个 v/vn/vt,我创建这个字符串的散列,例如 nHashId = hash("80/50/1")* 并在地图中搜索散列。如果不存在,我创建一个 CustomVertex 并将其添加到向量中,然后将新创建的哈希和 CustomVertex_index 添加到地图中。

*:通过创建 v/vn/vt 字符串的哈希,我正在创建一个与该字符串对应的唯一数值,我希望在地图中搜索/比较它比等效文本更快。

如果我遇到哈希匹配,我认为 customvertex 已经存在,而不是创建新的 CustomVertex,我只是将 CustomVertex_index 条目添加到索引向量并继续前进。

由于这似乎是一项计算成本很高的练习,我想我会将我的 CustomVertex 数组(和相应的索引数组)转储到磁盘以供以后检索,而不是每次都解析 obj 文件。

在我提出问题之前,我是否可以指出,由于时间限制并且不想重新设计我的 Vbo 类(一项不平凡的任务),我坚持使用 CustomVertex 格式 - 我知道它可以提供属性将数组与我的着色器分开,但我已经读过像使用 CustomVertex 一样交错数据可以提高性能。

所以我的问题是: 1. 我的方法看起来是合理的还是疯狂的?如果疯了,请指出我哪里出错了。

  1. 你能发现任何潜在的问题吗?

  2. 有没有人这样做过并且可以推荐一种更简单的方法来实现我想要的?

4

2 回答 2

0

这个想法不是创建“v/vn/vt”的字符串散列,而是仅将 v 散列为整数。之后,您将获得一个包含共享相同 v 索引的所有“v/vn/vt”组合的存储桶。

如果发生哈希冲突(遇到相同的 v),您会将冲突的组合与桶中的组合进行比较,以查看它是否真的重复。如果没有,请记住将碰撞的组合添加到存储桶中。

于 2014-04-17T18:00:15.047 回答
0

你能发现任何潜在的问题吗?

你的意思是除了哈希冲突?因为我没有看到处理该问题的算法部分。

有没有人这样做过并且可以推荐一种更简单的方法来实现我想要的?

有一个更简单的方法:只比较索引而不使用哈希。

于 2013-01-04T02:02:32.257 回答