为什么我的OBJ解析器渲染这样的网格? [英] Why is my OBJ parser rendering meshes like this?

查看:224
本文介绍了为什么我的OBJ解析器渲染这样的网格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我自己就把OBJ解析器/导入器支持添加到我一直在研究的3D渲染引擎上。我遵循了发现这里几乎'发球'的规格,限制对组,面,顶点,法线和纹理坐标的所有支持的当前异常(因此没有材料库或自由格式多边形支持)。我的目标是简单地逐行解析 - 在我进行时生成面向对象的,分层的树状场景图 - 并允许开发人员自动将数据绑定到着色器程序,只需很少的手动调用开始操纵&查看网格。最终结果是我的引擎成功解析了大多数(如果不是所有)有效的OBJ格式文件,提取适当的数据并将其发送到基本着色器进行渲染。但是,即使数据似乎在场景图中正确显示,由于某种原因它很少正确呈现...

I've taken it upon myself to add OBJ parser/importer support to a 3D rendering engine I've been working on. I've followed the specification found HERE nearly 'to a tee', with the current exception of limiting all support to groups, faces, vertices, normals and texture coordinates (so no material library or free-form poly support, as of yet). My goal was to simply parse line by line -- generating an object-oriented, hierarchical tree-like scene graph as I went along -- and allow the developer to automatically bind the data to a shader program with very few manual calls in order to start manipulating & viewing the mesh. The end result is that my engine does successfully parse most (if not all) valid OBJ format files, extracting the appropriate data and sending it to a basic shader for rendering. However, even though the data appears to be represented correctly in the scene graph, for some reason or another it rarely renders properly...

请注意一个简单的平面(从3DS Max导出,只包含4个顶点和2个面)渲染完全正常,但是立方体或任何更高级的东西通常最终看起来像这样:

Take note that a simple plane (exported from 3DS Max, containing only 4 vertices and 2 faces) renders perfectly fine, but a cube or anything more advanced usually ends up looking something like this:

http://youtu.be/1x6bnuhAXWY

我不能告诉事情出了什么问题,AFAIK我的代码实际上应该解析并渲染基本的几何图形......那么为什么不呢?为方便起见,我上传了在此投影。它包含一个NetBeans项目,其中包含我的引擎的最小版本和一个Test应用程序。我还包括3个不同版本的OBJ立方体网格和单个平面网格。可以通过编辑Test.java顶部的值来配置应用程序,并且唯一的输入控件是A,S,W和& D用于网格平移,以及用于网格旋转的鼠标移动。虽然我已经设法大幅度减少了项目,但最值得注意的课程包括文件顶部的额外评论/信息。

I can't tell where things are going wrong, and AFAIK my code should actually be parsing and rendering basic geometry just fine... So why isn't it? For convenience, I have uploaded my project HERE. It contains a NetBeans project with a minimal version of my engine, and one Test application. I have also included 3 different versions of an OBJ cube mesh, and a single plane mesh. The application is configurable by editing the values at the top of Test.java, and the only input controls are A, S, W, & D for mesh translation, and mouse movement for mesh rotation. And although I've managed to skim the project down considerably, the most notable classes include extra comments/info at the top of the file.

考虑到所有事情,我我会采取任何我能得到的想法...而且它肯定不会被不受重视!

All things considered, I'll take whatever thoughts I can get... and it certainly won't go unappreciated!

推荐答案

我还没有下载你的项目。在编写用于使用OpenGL渲染的OBJ导入代码时,人们最挣扎的是索引。正如@ratched_freak在评论中也怀疑,这与你的立方体的视觉外观非常一致。

I haven't downloaded your project. What people mostly struggle with when writing OBJ import code for rendering with OpenGL is the indices. And as @ratched_freak also suspects in his comment, that's very consistent with the visual appearance of your cube.

OBJ格式对位置,法线和纹理坐标使用单独的索引。对于OpenGL渲染,您需要一组索引。这意味着您需要为OBJ文件中三角形使用的位置/法线/纹理索引的每个唯一组合生成顶点,为组合分配新索引,然后在OpenGL索引缓冲区中使用该索引。

The OBJ format uses separate indices for positions, normals, and texture coordinates. For OpenGL rendering, you need a single set of indices. This means that you need to generate a vertex for each unique combination of position/normal/texture indices used by triangles in the OBJ file, assign a new index to the combination, and then use that index in your OpenGL index buffer.

我用伪代码写了一个答案,其中概述了最近如何针对类似问题执行此操作: OpenGL - 索引缓冲困难

I wrote an answer with pseudo-code that outlines how to do this for a similar question recently: OpenGL - Index buffers difficulties.

编辑,以更多地说明问题。这是我在网上找到的立方体文件:

Edit, to illustrate the problem some more. Here is a "cube" file I found online:

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)。

The file has 8 positions (v records) and 6 normal (vn records). The f records are faces, triangles in this case. Looking at the first triangle vertex, 1//2 tells you that the vertex uses position 1 and normal 2. When using OpenGL index arrays, you can't have separate indices for positions and normals. So we create a vertex for this position/normal pair, and assign it the first available index. Same for 7//2 and 5//2, so we now have 3 OpenGL vertices (indices 0, 1, and 2).

现在在第二个三角形上,我们再次找到 1 // 2 。我们已经为这个组合创建了一个顶点,所以我们可以再次使用我们的顶点0。 3 // 2 是新的,所以我们为它创建一个新的顶点(索引3)。 7 // 2 我们之前看到,它与我们的顶点1相同。

Now on the second triangle, we find 1//2 again. We already created a vertex for this combination, so we can use our vertex 0 again. 3//2 is new, so we create a new vertex (index 3) for it. 7//2 we saw previously, it's the same as our vertex 1.

所以我们最终得到4第一个2个三角形的OpenGL顶点。这是有道理的,因为两个三角形描述了立方体的一个面,我们需要4个顶点作为正方形。

So we ended up with 4 OpenGL vertices for the fist 2 triangles. Which makes sense, since the two triangles describe one face of the cube, and we need 4 vertices for a square.

如果你继续整个例子的这个过程,你最终将有24个顶点,你可以存储在OpenGL顶点缓冲区,以及一个包含36个条目的索引缓冲区(12个三角形,每个3个角)。

If you continue this process for the whole example, you will end up with 24 vertices you can store in an OpenGL vertex buffer, and an index buffer with 36 entries (12 triangles with 3 corners each).

这篇关于为什么我的OBJ解析器渲染这样的网格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆