Wings3D .obj file -> OpenGL problem

Member
Posts: 321
Joined: 2004.10
Post: #1
I went into wings3D and created a simple cube. I then
exported it to a .obj file. This is what was created:


Code:
# Exported from Wings 3D 0.98.32a
mtllib Cube.mtl
o /Users/kyle/Desktop/Square.ai
#8 vertices, 6 faces
v 0.25416750 -0.18833250 0.10000000
v 0.25416750 0.18833250 0.10000000
v -0.25416750 0.18833250 0.10000000
v -0.25416750 -0.18833250 0.10000000
v 0.25416750 -0.18833250 -0.10000000
v 0.25416750 0.18833250 -0.10000000
v -0.25416750 0.18833250 -0.10000000
v -0.25416750 -0.18833250 -0.10000000
vn 0.57735027 -0.57735027 0.57735027
vn 0.57735027 0.57735027 0.57735027
vn -0.57735027 0.57735027 0.57735027
vn -0.57735027 -0.57735027 0.57735027
vn 0.57735027 -0.57735027 -0.57735027
vn 0.57735027 0.57735027 -0.57735027
vn -0.57735027 0.57735027 -0.57735027
vn -0.57735027 -0.57735027 -0.57735027
g /Users/kyle/Desktop/Square.ai_default
usemtl default
f 1//1 5//5 6//6 2//2
f 2//2 3//3 4//4 1//1
f 2//2 6//6 7//7 3//3
f 3//3 7//7 8//8 4//4
f 4//4 8//8 5//5 1//1
f 5//5 8//8 7//7 6//6


The .obj is then read into my OpenGL file for a wire frame object.

Not sure what I'm doing, but I looked at a StanfordBunny example for
a starting place with the following code:

Code:
int listID = glGenLists(1);   // start the display list
   glNewList(listID, GL_COMPILE);
  
   glLineWidth( 3.0 );
  
   glBegin(GL_LINE_LOOP);
  
   while ( inFile >> token )
   {
         inFile >> x >> y >> z;  // read in vertex
         glVertex2d( x, y, z );  
      }        
   }      
   glEnd ();  
   glEndList();


At least I get something, but It's not a cube; more like two
upright parallel squares with a connecting X at their bottom face.

I also try and create a solid object from the same data. With
the following:

Code:
int listID = glGenLists(1);   // start the display list
    glNewList(listID, GL_COMPILE);

    int maxNum = faceIndices.size();
    
    //glBegin (GL_TRIANGLES);
    //glBegin (GL_LINE_LOOP);
    glBegin (GL_QUADS);
    for( int i = 0; i < maxNum; i=i+6 )
    {
       int vx = faceIndices[i];  
       int vnx = faceIndices[i+1];
      
       int vy = faceIndices[i+2];  
       int vny = faceIndices[i+3];
      
       int vz = faceIndices[i+4];  
       int vnz = faceIndices[i+5];
              
       glVertex3d(vertices[vx], vertices[vy], vertices[vz]);
            
       glNormal3d( vertexNormals[vnx], vertexNormals[vny], vertexNormals[vnz]);                                        
    }
    glEnd ();
    glEndList();


Instead of solidcube, I get sort of two bent solid triangles kinda arranged
about a cube.

Anybody see my mistake(s)?

thanks.
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #2
I don't think you understand the concept of obj files very well. You have the vertex list, then you have the faces. The faces are what you use to create the actual shape. What you will need to do is read in all the vertices, vertex texture coordinates, and vertex normals. Once you do that, you will need to read in the indices that the faces give you (those indices start at 1 for some odd reason), and resolve those into the correct vertices, vertex texture coordinates, and normals. This is no small task, mainly because they are stupid and don't provide the item counts for obj files. (Mad) I just completed the obj loader for a program I'm making that will assist me in putting models into games. (the final format will be a binary format of my making, though, which will be much faster in loading as well as smaller) The function to load the obj files is 900 lines long, and I have 2 specially created linked lists, one to find the counts that I need for the indices for the vertex arrays, and one to assist in resolving which index points to which vertex. (and also removes copies of vertices) This also includes material file importing, though.
Quote this message in a reply
Moderator
Posts: 529
Joined: 2003.03
Post: #3
Some apps do put those counts in a comment block.

"Yes, well, that's the sort of blinkered, Philistine pig-ignorance I've come to expect from you non-creative garbage."
Quote this message in a reply
Member
Posts: 114
Joined: 2005.03
Post: #4
The first code should have glVertex3d instead of glVertex2d.
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #5
Now, for some actual help:

1. Go here: http://www.sfu.ca/~kberg/Code/sourcecode.html
2. Download the source for the wavefront obj loader.

You won't be able to write your own, and this one works.
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #6
Also, don't forget that .obj starts indexing at one, not zero.
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #7
LongJumper Wrote:You won't be able to write your own, and this one works.

A rudimentary .obj loader is trivial to write. I did it in an evening. If you want a full-featured loader, it would take a little bit more effort, but really not that much.
Quote this message in a reply
Member
Posts: 321
Joined: 2004.10
Post: #8
Quote:A rudimentary .obj loader is trivial to write. I did it in an evening.

Maybe for you, but it would take me a month and even
then not work right Smile

I'll try the loader first. Also study the code; should learn alot.

thanks all!
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #9
I was trying to relate to his abilities at this point in time. That "you" was not a universal quantifier Wink

Good luck, that .obj loader was one of the big stepping stones for learning OpenGL for me.
Quote this message in a reply
Member
Posts: 321
Joined: 2004.10
Post: #10
Just for closure:

I Downloaded that .obj loader (just 2 files - ModelType.h and ModelType.cpp),
moved it into my Xcode project, put in a LoadObj() and Draw() method
calls into my code, recompiled, and bam! Perfect openGL 3D drawings.
It doesn't get better that this.

BTW, I did look at the loader and code and yes it has me stymied. I'll study and undersand it eventually, but right now I'm just having too much 3D fun.

If any 3D newbie is reading this, I can't recommend highly enough Wings3D
and the above link to the (.obj loader) ModelType class.

Thanks again all!
Quote this message in a reply
eShad0w
Unregistered
 
Post: #11
WhatMeWorry Wrote:I Downloaded that .obj loader (just 2 files - ModelType.h and ModelType.cpp),
moved it into my Xcode project, put in a LoadObj() and Draw() method
calls into my code, recompiled, and bam! Perfect openGL 3D drawings.
It doesn't get better that this.

Thanks again all!

Huh Can you please be more specific with that, what and where exactly should I put in my project in order for it to load (call) my obj file?
Quote this message in a reply
Member
Posts: 260
Joined: 2005.05
Post: #12
LongJumper Wrote:Now, for some actual help:

1. Go here: http://www.sfu.ca/~kberg/Code/sourcecode.html
2. Download the source for the wavefront obj loader.

You won't be able to write your own, and this one works.
Writing an OBJ loader, at least a basic one that loads straight mesh data is very straight forward. (OBJs hold some more data, like spline representations, but I never touched them.) I have looked at several OBJ samples, but still find it easier to write my own, since I otherwise must rewrite much of someone else's code to adjust the output format and add postprocessing. I have actually done the whole thing twice - with post processing. (I wasn't happy with the first module so I wrote a new one rather than fixing the old one.)

With post processing, I mean breaking down polygons to triangles (so I can use glDrawElements and similar), and calculating texture coordinates and normal vectors, in case they are not provided in the OBJ. That's a lot more work, but still quite managable.
Quote this message in a reply
Member
Posts: 22
Joined: 2006.04
Post: #13
I'm trying to do a similar thing - read a .obj file and display it. I'm using GLUT and C++ atm.

I've been using models with no texture data to start off with and I got to the stage (in an evening) where I could read in all the vertices, normals and face information fine and various models all displayed happily using GL_LINE as the polymode for back and front faces (wireframe).

Now I'm trying to display these models with GL_FILL and basic lighting and I've run into a problem: the vertices for the faces don't seem to be consistently specified in order in the .obj - i.e. some are clockwise, some are anticlockwise. So my display routine draws some faces the right way round, some the wrong way round and the normals are reversed for some and not for others.

I've loaded the same models into Blender and it displays them fine, so presumably there is a way of fixing this.

Is there an obvious way of telling which faces are specified anti-clockwise and which are clockwise so I can reverse them? Is there another kind of solution? Or does it sound like something else is wrong?

Any help would be appreciated...

G
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #14
flash: are you remembering that the vertices you read in will probably be stored in a 0 index array and the polygons in an obj file reference vertices with a starting index of 1?

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #15
flash: I've never had a problem with Wings' export, but maybe Blender doesn't do such a good job.

You can tell which way the polygon is wound by looking at the dot product of the vertex normals with the face normal, I think.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  OpenGL Alpha Channel Problem Moganza 1 3,133 Jan 19, 2013 08:25 AM
Last Post: sealfin
  iPad, OpenGL ES, and XCode Instruments problem! Bandit 0 3,946 Dec 13, 2010 01:21 PM
Last Post: Bandit
  OpenGL global and local coordinate problem. mikey 4 3,985 May 26, 2009 08:48 AM
Last Post: mikey
  Simple OpenGL ES problem soulstorm 3 4,229 May 14, 2009 03:53 PM
Last Post: AnotherJake
  Opengl picking problem (zip file) papillon68 1 4,508 Mar 1, 2009 08:49 PM
Last Post: chronus