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...
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:
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!
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.
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.
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
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).
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.
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.
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).
来源:https://stackoverflow.com/questions/23710829/why-is-my-obj-parser-rendering-meshes-like-this