[英]parsing the wavefront obj file format
我想将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个tex coords和80个法线。
以这种格式列出约390个面孔之后:
f 83/42/1 67/46/1 210/42/1
我在文件中遇到以下内容:
#
# object tile00
#
然后是更多的顶点定义。
因此,我推断出一个模型可能包含几个子对象,每个子对象由多个面定义; 每个面由3 x顶点/法线/ 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。我的方法看起来是合理的还是疯狂的? 如果疯了,请指出我出错的地方。
你能发现任何潜在的问题吗?
有没有人以前做过这个并且可以推荐一种更简单的方法来实现我想要的东西?
你能发现任何潜在的问题吗?
你的意思是除了哈希冲突? 因为我没有看到你的算法部分处理它。
有没有人以前做过这个并且可以推荐一种更简单的方法来实现我想要的东西?
有一个更简单的方法:只是比较索引而不是使用哈希。
不是创建“v / vn / vt”的字符串哈希,而是仅将v作为整数哈希。 之后,您将获得一个包含共享相同v索引的所有“v / vn / vt”组合的存储桶。
如果发生哈希冲突(遇到相同的v),您可以将冲突的组合与桶中的组合进行比较,以查看它是否真的重复。 如果没有,请记住将碰撞的组合添加到桶中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.