Thursday, October 16, 2008

iPhone 3D object spinning retrospect

Wow, it works. Last time I was trying to outline what I would need to get a 3D object loader and displayer working, and now about three days later it works -- I have a mushroom I created in Meshworks spinning smoothly on the iPhone. Quite pretty. Now let's see what I listed three days ago and see how it panned out.

I thought I would need bitmaps for the textures and which texture to use with which mesh. Well of course that would be more complicated, I realized I would need texture coordinates as well for each vertex. I decided that texture mapping at this point is not important, I cannot allow myself to become one of those people who tinker on a 3D engine on their spare time. No, this has to become a playable game as fast as possible, and texture mapping usually isn't totally essential to gameplay.

I figured I'd need to have a list of meshes. Now I have a nice 3D object class, each object of which contains 3D mesh instances. Each mesh then contains a vertex list and additionally the color of the mesh, which I could easily get from the file I parse. I was worried about the vertex etc. data loader being complex, but actually taking some shortcuts it is easy to get that information out from a WRL file outputted by Meshworks. I didn't attempt to write a general WRL reader, mine only understands the specific output of Meshworks, so if there is some extra whitespace in the wrong place, it wouldn't work. That means I made the decision to stick with Meshworks, even this particular version of it.

I supposed there would be a list of vertices, then another list of triangles referring to the vertice list. That's how it really was in the WRL file. I made the unnecessary move of rolling out from that data a plain polygon list with no shared vertices, but turns out OpenGL ES would have known how to do that by itself.

I had totally ignored lighting in my original list. To know the brightness of each polygon, I had to specify where the lights are, and the material properties like how strong specular highlights should be on a surface. And to be able to compute these things, of course OpenGL then wanted to know where the surface normals are pointing. I tried to refer to my linear algebra text, but in the end did the copypasta PHP coder thing and just copied the normal calculation routine from some sample code. Well, maybe I mistyped something, but I had to tweak it for hours before it actually calculated the normals correctly. It was really difficult to debug, because just looking at float values in a debugger it's not so easy to say if a vector is pointing to the correct direction.

Another thing I ignored was setting up the projection to look OK. When you create a sample project in Xcode, initially it sets you up with 2D projection. All the sample code on the net refers to some GLU functions to set up a perspective projection, but those are missing from my framework. I guess the right thing to do may have been to again learn from my lin. algebra text how to REALLY do it, but instead I again just copied a working projection matrix from an example. Just too eager to get this project forward!

I've learned a great deal about OpenGL in the past 3 days, and it's exciting to be able to rather easily display 3D objects now. Hopefully this will be useful later, and not just a distraction. I'll try to blog some more about my progress soon.