我自己就把OBJ解析器/导入器支持添加到我一直在研究的3D渲染引擎上。我已遵循规范found HERE几乎'到'tee',目前的例外是限制对组,面,顶点,法线和纹理坐标的所有支持(因此没有材料库或自由形式的poly支持,如然而)。我的目标是简单地逐行解析 - 在我进行时生成面向对象的,分层的树状场景图 - 并允许开发人员自动将数据绑定到着色器程序,只需很少的手动调用开始操纵&查看网格。最终结果是我的引擎成功解析大多数(如果不是所有)有效的OBJ格式文件,提取适当的数据并将其发送到基本着色器进行渲染。但是,即使数据似乎在场景图中正确表示,由于某种原因它很少正确渲染......
请注意,一个简单的平面(从3DS Max导出,只包含4个顶点和2个面)渲染得非常好,但是立方体或任何更高级的平面通常最终看起来像这样:
我无法分辨出问题出在哪里,AFAIK我的代码实际上应该解析并渲染基本的几何图形......那么为什么不呢?为方便起见,我上传了project HERE。它包含一个NetBeans项目,其中包含我的引擎的最小版本和一个Test应用程序。我还包括3个不同版本的OBJ立方体网格和一个平面网格。可以通过编辑Test.java顶部的值来配置应用程序,并且唯一的输入控件是A,S,W和& D用于网格平移,以及用于网格旋转的鼠标移动。虽然我已经设法大幅度减少了项目,但最值得注意的类包括文件顶部的额外注释/信息。
考虑到所有事情,我会采取任何我能得到的想法......而且肯定不会不受重视!
答案 0 :(得分:6)
我没有下载你的项目。在编写用于使用OpenGL渲染的OBJ导入代码时,人们最挣扎的是索引。正如@ratched_freak在评论中也怀疑,这与你的立方体的视觉外观非常一致。
OBJ格式对位置,法线和纹理坐标使用单独的索引。对于OpenGL渲染,您需要一组索引。这意味着您需要为OBJ文件中三角形使用的位置/法线/纹理索引的每个唯一组合生成顶点,为组合分配新索引,然后在OpenGL索引缓冲区中使用该索引。
我用伪代码写了一个答案,其中概述了最近如何针对类似问题执行此操作:OpenGL - Index buffers difficulties。
编辑,以更多地说明问题。这是我在网上找到的“立方体”文件:
v 0.0 0.0 0.0
v 0.0 0.0 1.0
v 0.0 1.0 0.0
v 0.0 1.0 1.0
v 1.0 0.0 0.0
v 1.0 0.0 1.0
v 1.0 1.0 0.0
v 1.0 1.0 1.0
vn 0.0 0.0 1.0
vn 0.0 0.0 -1.0
vn 0.0 1.0 0.0
vn 0.0 -1.0 0.0
vn 1.0 0.0 0.0
vn -1.0 0.0 0.0
f 1//2 7//2 5//2
f 1//2 3//2 7//2
f 1//6 4//6 3//6
f 1//6 2//6 4//6
f 3//3 8//3 7//3
f 3//3 4//3 8//3
f 5//5 7//5 8//5
f 5//5 8//5 6//5
f 1//4 5//4 6//4
f 1//4 6//4 2//4
f 2//1 6//1 8//1
f 2//1 8//1 4//1
该文件有8个位置(v
个记录)和6个普通(vn
个记录)。在这种情况下,f
记录是面,三角形。查看第一个三角形顶点,1//2
告诉您顶点使用位置1和法线2.使用OpenGL索引数组时,不能为位置和法线分别设置索引。因此,我们为此位置/法线对创建一个顶点,并为其指定第一个可用索引。 7//2
和5//2
相同,因此我们现在有3个OpenGL顶点(索引0,1和2)。
现在在第二个三角形上,我们再次找到1//2
。我们已经为这个组合创建了一个顶点,所以我们可以再次使用顶点0。 3//2
是新的,所以我们为它创建一个新的顶点(索引3)。我们之前看到的7//2
,它与我们的顶点1相同。
因此我们最终得到了4个OpenGL顶点,用于第一个2个三角形。这是有道理的,因为两个三角形描述了立方体的一个面,我们需要4个顶点作为正方形。
如果对整个示例继续此过程,最终将有24个顶点可以存储在OpenGL顶点缓冲区中,以及一个包含36个条目的索引缓冲区(12个三角形,每个3个角)。