我希望将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
};
我正在使用从互联网下载的一个小木屋模型进行工作。
这个小木屋有许多顶点、法线和纹理坐标定义,后面是一系列面的定义。
于是我的第一个想法是解析OBJ文件,最终得到:
vector<vertex>
vector<Normal>
vector<TexCoord>
这并不容易转换成我的CustomVertex格式,因为文件中可能定义了210个顶点、100个纹理坐标和80个法线。
在这种格式下,列表中有约390个面:
f 83/42/1 67/46/1 210/42/1
我在文件中遇到了以下问题:
#
# object tile00
#
接下来是更多的顶点定义。
因此,我推断一个模型可能由几个子对象组成,每个子对象由若干个面定义;每个面由3个顶点/法线/纹理坐标索引值定义。
因此,为了得到一个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条目添加到indices向量中并继续前进。
由于这似乎是一个计算上昂贵的练习,我猜我会将我的CustomVertex数组(和相应的indices数组)转储到磁盘上以供稍后检索,而不是每次解析obj文件。
在我提出问题之前,我可以指出,由于时间限制并且不想重新设计我的Vbo类(一个非常重要的任务),我被困在了CustomVertex格式中 - 我知道可以将属性分别提供给我的着色器,但我已经阅读过像我所拥有的CustomVertex一样交错数据可以增强性能。
那么我的问题是: 1.我的方法听起来合理还是疯狂?如果疯狂,请指出我错在哪里。
- 您能发现任何潜在问题吗?
- 有人做过这个并且可以推荐更简单的方法来实现我正在尝试的内容吗?
unordered_map
呢?否则,你的方法看起来很好,也不会过于复杂。 - pmr