Interpreting a Wavefront Obj...

I need some help interpreting a WavefrontOBJ File. For example, at its simplest, I have the following cube:

Object “object01”:

ComRec:

g cube01

No. points 8:

v -0.5 -0.5 -0.5
v -0.5 -0.5 0.5
v -0.5 0.5 -0.5
v -0.5 0.5 0.5
v 0.5 -0.5 -0.5
v 0.5 -0.5 0.5
v 0.5 0.5 -0.5
v 0.5 0.5 0.5

No. normals 30:

vn 0 0 -1
vn 0 0 1
vn -1 0 0
vn 1 0 0
vn 0 1 0
vn 0 -1 0
vn 0 0 -1
vn 0 -1 0
vn -1 0 0
vn 0 0 1
vn 0 -1 0
vn -1 0 0
vn 0 0 -1
vn 0 1 0
vn -1 0 0
vn 0 0 1
vn 0 1 0
vn -1 0 0
vn 0 0 -1
vn 0 -1 0
vn 1 0 0
vn 0 0 1
vn 0 -1 0
vn 1 0 0
vn 0 0 -1
vn 0 1 0
vn 1 0 0
vn 0 0 1
vn 0 1 0
vn 1 0 0

No. texture coordinates 8:

vt 0 0
vt 0 0
vt 0 1
vt 0 1
vt 1 0
vt 1 0
vt 1 1
vt 1 1

No. faces 6:

f 3/3/13 7/7/25 5/5/19 1/1/7
f 6/6/22 8/8/28 4/4/16 2/2/10
f 2/2/12 4/4/18 3/3/15 1/1/9
f 7/7/27 8/8/30 6/6/24 5/5/21
f 4/4/17 8/8/29 7/7/26 3/3/14
f 5/5/20 6/6/23 2/2/11 1/1/8

The first section, the vertexes, clearly sow a cube. I can also see that I have to somehow utilise the last section, the indexes to arrange and draw them onto the screen…

Can any tell me how I can draw this cube onto the screen using OpenGL ?

google for:
wavefront obj file format

some tips:
-the ‘f’ entries define index arrays for vertices, normals and texture coordinates - they’re 1-based
-if there are multiple objects in the file then vertex indices do not start from 1 for each object. In other words: one .obj file cannot define two vertices having the same index.

So an example:
o test -beginning of object named ‘test’
v 0.0 0.0 0.0 -vertex 1
v 1.1 2.2 3.3 -vertex 2
v 4.4 5.5 6.6 -vertex 3
vn 0.0 0.0 1.0 -normal 1
f 1/1 2/1 3/1 -a triangle (vertex/normal vertex/normal…)
f 3/1 2/1 1/1 -another triangle
o test2 -beginning of object ‘test2’
v 7.7 8.8 9.9 -vertex 4
v 1.7 3.8 5.9 -vertex 5
v 2.7 4.8 6.9 -vertex 6
vn 0.0 1.0 0.0 - normal 2
vn 0.0 1.0 0.0 - normal 3
f 4/2 5/2 6/3 -triangle using 2 vertices and 2 normals

f v1/vn1/t1 v2/vn2/t2 v3/vn3/t3
In its simplest form a face can consist of three vertices, making up a triangle. The first parameter gives you the vertex number. When you parse the vertices, the first vertex has index 1, the second vertex has index 2 etc. The same with the vertex normals, the first vertex normal has index 1 etc. In the above example v1 is the number of the first vertex of the face, vn1 is the corresponding vertex normal, and t1 is the corresponding texture coordinate of that vertex. Once you store each face in a data structure so that you can access these variable directly, you can render the .obj file like the following:

for each face of the model
glBegin(GL_POLYGON);
for each vertex of the face
glTexCoord1f(t);
glNormal3f(vn.x, vn.y, vn.z);
glVertex3f(v.x, v.y, v.z);
end
glEnd();
end

voila!

Thanks…but…

Say, For example this index: … “2/2/10” (End of second line)

This corresponds to
2nd vertex: v -0.5 -0.5 0.5
2nd normal: vn 0 0 1
10th tex co-ord: ??

Right ? But if so, there are only 8 textureco-ordinates ?

EDIT: Maybe it is vertex pos/normal/tex co-ord,as opposed to vertex pos/tex co-ord/normal ?

I just did what I suggested in my first post - googled for: wavefront obj file format. First page I’ve found answers your question - values are: pos/normal/tex

Yes, but pos/normal/tex wouldn’t work ? Which is the reason for this post…

Read my last about “2/2/10” … There isn’t 10 tex co-ords, so pos/normal/tex wouldn’t be possible…

Oh wait…

First page from google:

“A polygonal face. The numbers are indexes into the arrays of vertex positions, texture coordinates, and normals respectively”

So it seems I was right… tis pos/tex/normal…

Thanks for the help everyone :slight_smile:

tex coords. and normals are optional, so you can have the following possibilities:
f 1 2 3
f 1/1 2/2 3/3
f 1//1 2//2 3//3
f 1/1/1 2/2/2 3/3/3

Right…

Now thats over, it leads me onto my next section …

How can I use the indices to draw this cube using OpenGL (preferabbly OpenGL|ES, so no glBegin/glEnd calls, just vertex arrays…) ??

oh and btw: Thanks all… :slight_smile:

Hehe - I messed up my answer about pos/normaltex, sorry. Good thing that you did google for that document and corrected my error yourself. Greetz!

Thanks k_szczech… No worries…

Any info on the second part of the question tho ?

Anyone ?

I want to how I can draw this cube (See first post)in OpenGL ?

What are you reading your information into?

Are you reading it into an array of some sort?

If you are, I recommend using either Vertex Arrays or Vertex Buffer Objects.

Yes, Vertex Arrays…

I can load the vertices quite simply into an array, but how do I use 'em ?

There are only 8 vertices … To draw a cube you would need 24… ?

I know it has something to do with faces, but … ?

Well, if you want to use normals and texture coordinates, then you will have to reorganise your vertex array.
Your vertex array will have 24 vertices, 24 normals and 24 texcoords. First load vertex coordinates, normals and texcoords to temporary arrays (directly from file). Then create new vertex arrays - copy vertices from your temporary arrays in order specified by faces.
To render a cube just call glDrawArrays.
If you do not use texture coordinates, then you can use only one normal vector for each face. This way you can have vertex array with just 8 vertices and call glNormal3fv and then glDrawElements once for each face. In this case you would only have vertex array (no texcoord array, and normals passed separately from CPU).

Each corner of a cube is a corner of 3 faces sharing one vertex, but unfortunately each of these faces has different normal vector.
A sphere for example is a continous (smooth) surface - you can share vertices between faces. In this case you can use glDrawElements instead of glDrawArrays.

Thanks ever so much k_szczech…

I think I know what to do now…

Just…, could you explain a lil more about: “glDrawElements” ? I’ve always used glDrawArrays before, and never glDrawElements…

Ok, I think simple example will be better than 1000 wise-wannabe words, so here goes:
Imagine a simple quad - so we have vertices 0-3.

glBegin(GL_QUADS);
 glVertex3f( <vertex0> );
 glVertex3f( <vertex1> );
 glVertex3f( <vertex2> );
 glVertex3f( <vertex3> );
glEnd();

When using glDrawArrays:

 glDrawArrays(GL_QUADS, 0, 4);

Now imagine that you want to use 2 triangles instead of one quad:

glBegin(GL_QUADS);
 glVertex3f( <vertex0> );
 glVertex3f( <vertex1> );
 glVertex3f( <vertex2> );

 glVertex3f( <vertex2> );
 glVertex3f( <vertex3> );
 glVertex3f( <vertex0> );
glEnd();

Vertex 0 and Vertex2 are used twice - they’re shared between these two triangles.
And now glDrawElements:

unsigned long indexArray[6] = {0, 1, 2, 2, 3, 0};
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexArray);

In other words - glDrawArrays will use vertices in exactly the same order they’re placed in vertex array and glDrawElements allows you to pass an array of integers. This array defines the order of vertices.

Hmm…

glDrawElements is still getting the vertices data from array tho (using glVertexPointer) ?

Thanks for the explanation btw … :slight_smile:

Anyone ?