This is the first post in what I hope to be a long series on DIY 3D game building using Objective-C (at least for starters, there's always the itch to start moving over to C++) and Blender. These posts will describe aspects of the graphics and game engine that I'm using for the game I'm working on: Captain Casual (you can see a walkthrough of one of the game's levels here via youtube).
In this first post, I'm going to start with the basic object data that the graphics engine is going to be working with: model data which consists of an array of vertices, normals, and uv coordinates. I'll also briefly describe the script that I've used to export data from Blender into binary interleaved data that will then be read into the graphics engine.
Since we are talking DIY 3D game development, it means you want to make your own models, and to do that you will need some software help. For Captain Casual, I've been using blender to make the game's ship models, like this Badger Class Conglomeration ship:
In one of my future posts, I'll go over everything I know about blender as it applies to model creation, but if you'd like to get a jump start, I highly recommend blender cookie's interface and modeling tutorials.
The format of the model data
All models that you make in blender will contain vertex positions: 3-dimensional coordinates for each vertex point in the model. Together these points describe the basic structure of the model. There are two other sources of data that the game engine is going to need for each vertex point: normals and UV coordinates. Normals are 3-dimensional vectors that describe the direction that each vertex is facing and they are used by the game engine for calculating how light will interact with the model (producing shadows and so on). UV Coordinates are 2-dimensional coordinates that map a 2-dimensional image onto the model. In blender, you can use the UV editor to detail your models using a 2-dimensional image, this process is referred to as UV mapping (blender cookie has a tutorial on UV mapping here). The UV map is described by 2D coordinates, one for each vertex (U and V are used to refer to the mapping coordinates because x, y, z, and w, are already commonly used for other purposes).
To recap then, for each vertex in the model there are three sets of data that will be needed: the position of each vertex in 3-dimensions (px,py,pz), the normal of each vertex described by a 3 dimensional vector (nx,ny,nz) and a 2-dimensional texture mapping coordinate for each vertex (u,v). So for each vertex in the model, we will be exporting 8 numbers: px py pz nx ny nz u v. In terms of how this information is going to saved to a file, the script will simply loop through all of the vertices and print out each of the 8 numbers for each vertex. This is also known as an interleaved format, and it is the way that Apple recommends passing model data to openGL (as per Apple's docs here).
Finally, to increase the speed at which the graphics engine can read in the model data and to reduce the size of the exported model files, the files will be exported as binary data.
The python script
The python script is a modified version of Jeff Lemarche's blender script to a c-header file (as described at his blog here). The primary modification that I've made has to do with the script's output and using struct.pack to produce a binary output.
The first thing the export script will write is the total number of vertices in the model (allowing the graphics engine to initialize an appropriately sized array), and then it will proceed to write the interleaved data. Here's a github gist of the script:
Installing & running the script
You can find detailed instructions on how to install blender scripts in Blender 2.6's documentation here
Once you've installed the script as an add-on, then select the model that you want to export, and select file->export-> model file (.model). In the bottom left hand pane you can check the different options that you'd like, but in general you'll want to leave them at their default settings.
Once you've run the script, if you would like to undo the changes that are made to your object (e.g., modifiers that are applied or changing the quads to triangles), a single undo command (command-Z on the mac, control-Z on the pc) in object selection mode will undo all of the changes that were made by the script.