Wavefront .Obj File Rendering

Started by
5 comments, last by ericbeg 13 years, 1 month ago
I've been working for about the past week attempting to write a parser for the .obj format. My engine already supports a custom type of file format so my idea was to simply try and convert the .obj into the type that my engine recognizes and can load and render.

So the example file is a file called xmas-ball.obj
http://pastebin.com/RKbQTX5R

And when converted to my format its something like this
http://pastebin.com/EcxqV5bM


The file format is simple. First it writes the vertex x,y,z followed by its normal x,y,z and texture coords u,v. Then at the bottom is a list of vertex indices.

Problem is something isn't right with the indices so that when rendered with GL_TRIANGLES (or any other variation) it becomes a big mess of connected points.

i.e.

screenshot1os.png
However when rendered with GL_POINTS you can see what it should look like. That tells me that the vertices are right.

i.e.

screenshotyt.png
The question is how to extract the indices (I just take the first from every triplet or duplet) so that they are pointing to the right vertices?
Advertisement
objs i believe had tris and quads, it looks like you need to convert them before saving to .obj. And make sure you subtract 1 from indices, because I think they start at 1 instead of 0.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

Yes and im still working on figuring out how to determine whether the obj should be rendered with tris or quads because i've seen some with both within the same group.

Also subrtacting the indices by 1 cleaned up the render a bit when using GL_QUADS

screenshot2qe.png
If you have a model with mixed quads and tris, what you can do is when you read a quad face, insert it in to your mesh as two triangles, and then render the mesh as tris. Yes, it will increase the number of indices, but after you're satisfied the model is loading correctly, you can them optimize and put the quads in one mesh buffer and the triangles in another, end render the object in two pieces. But beware, rendering the model in two draw calls, one for tris and another for quads, might still be slower than rendering one chunk of triangles.

One really annoying thing about OBJ files which tripped me up when writing my parser was the fact that the vertex, texture and normal coordinates don't have to match. Whereas in every rending library I can think of (including GL), these are usually specified together.

For instance, you'd think someone would be nice and write this:

f 1/1/1 5/5/5 2/2/2
f 3/3/3 4/4/4 2/2/2

But instead, you can end up with files like this:

f 1/2/4 3/4/3 2/5/2
f 3/1/2 3/4/3 2/5/2

What that means is for the first face, 1/2/4, that means take the 1st vertex coordinate, the 2nd texture coordinate and the 4th normal. Sure, you can read those values and put them in one of the vertices in your VBO, but then you realize if you want to reuse vertices when rendering, you need to remember that 1/2/4 is already in the VBO and already has an index. And if you come across a 1/3/4, that will need to be a NEW vertex in your VBO. Such a pain!

Think 'gross' files like that don't exist in the wild? Think again; I was trying to render an OBJ created by MakeHuman, and needed to write a bunch of extra code to handle these weird cases!

Good luck with your loader. If you're interested I can put my loaded up somewhere; I am planning on releasing my work-so-far renderer on github soon.
Those aren't really 'weird' or 'gross' cases, all OBJs are like that. OBJ is designed for minimum file size, while OpenGL is optimized for speed. Also I believe OBJ files were invented in the 1980s, long before anyone had VBO indices to worry about.
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
Those aren't really 'weird' or 'gross' cases, all OBJs are like that. OBJ is designed for minimum file size, while OpenGL is optimized for speed. Also I believe OBJ files were invented in the 1980s, long before anyone had VBO indices to worry about.[/quote]

That's a good point, OBJ is old. No way they would know the best organization for today! Back then it was perfectly acceptable (and preferable) to make it as small as possible.


edit: I just downloaded and rendered this xmas-ball object. It found a bug in my parser! I hadn't realized that the face command 'f' can specify arbitrary-n polygons: not just triangles and quads. This model contains a few hexagons and 1 octagon! I break them out into triangles.
Hello,

In my opinion, obj is indeed an old file format but it still is a good format to use with nowadays computer graphics.
The storing format and the rendering format should not be the same since they have different purpose.
So yes, it need some works to bring a stored model to a render-able one.

This topic is closed to new replies.

Advertisement