我想将 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. 我的方法看起来是合理的还是疯狂的?如果疯了,请指出我哪里出错了。
你能发现任何潜在的问题吗?
有没有人这样做过并且可以推荐一种更简单的方法来实现我想要的?