Friday, December 19, 2008

Wavefront OBJ Loader - Normals Done...

Normals have been a pain in my backside. There are a couple of things I didn't know before, that I definitely know now. For example, calls to glNormalPointer() have pass a pointer to completely different data based on the type of shading you're using. If you're using GL_FLAT smoothing, then you have to pass an array of surface normals, one per triangle (really, it's per polygon, but since OpenGL ES only supports triangles, it amounts to the same thing). On the other hand, if you're using GL_SMOOTH, then you have to pass in vertex normals.

The OBJ file can provide vertex normals, but is not required to. I originally coded this so that it read the vertex normals from the file if they were there, but since calculating surface normals is easier to do from a polygon then it is to back it out of the vertex normals, I decided to basically ignore the normals provided in the file and just calculated them each time.

If you use a 3D program that exports the vertices with clockwise vertex ordering rather than the default counter-clockwise, you may have to flip the calculated normals. There is an inline function provided to do that, but I think most programs should export correctly.

Right now, you have to manually switch from using vertex to surface normals and back depending on what type of shading you're using, though they are both calculated when the model loads. I'm going to look at using the correct one based on the shading.

Anyway, here you can see a screenshot with plane model using snazzy lighting and smooth shading.



So, that means that handling texture coordinates is the only major bit of functionality that's missing. Not sure when I'll get to that, though - I've got a bunch of paying work that I need to get done before the end of next week. Plus, I have to find or make some models that have texture maps.

Here is the project with the current version of the OBJ loader

No comments:

Post a Comment