I feel good about the game engine that I've developed while working on Light Racer. The only big thing that will be different about Light Racer 3D is that instead of drawing 2D sprites, each object will need to be rendered as 3D. To me, this sounds very simple. I plan on modeling everything in the game in 3D Studio Max, developing custom bits of rendering code then merging the 3D world renderer with the existing code base and tweaking to perfection. I'm confident that this will work, yet I'm pretty bad with 3DS, I've never developed anything in OpenGL, much less ES, and I have no existing tools to help me on my way. There has been a lot of reading and experimenting done, but at the end of the day, I have a working scene and a working OBJ file importer that maps textures correctly.
Here are some of the resources I've found most helpful in getting started with OpenGL ES:
The OpenGL ES 1.1 Reference Manual
This intro/tutorial on OpenGL Coordinate systems
This collection of tutorials of various OpenGL functions
The Google IO Presentation - Writing Real-Time Games in Android
Starting an OpenGL ES project from scratch can be seemingly impossible if it's your first time. Most likely, you will just end up with a black screen. I started with an example from the API demos. I believe I used the rotating cube. I started learning by just messing around with the cube. I'd add more cubes, make some bigger and some smaller, move some around, change colors, change rotations, change camera angles, etc. These are things you can do just to learn how the different transformations affect the scene.
Once I started to get the hang of that, I figured that I could create an Arena object and render it. I copied the cube to Arena and worked out the difference of Geometry. I pass in the width, height and depth on the constructor and build geometry to match. I also had to flip around the order of indices to make the triangles for the faces because I wanted the inside faces showing, not the outside. I removed the top and voila, I have a working arena!
A Note on Fixed Point conversions - 1.0 in floating point = 1 << 16 in fixed point. You can easily convert from float to fixed point by multiplying by 0x10000, since that is 16 bits. Try to do everything you can in fixed point. Floats will be slower!
This is where I had the most problems. I found so many tutorials on OpenGL that would show how to put in texture coordinates for every vertex but OpenGL ES doesn't allow for point-by-point definition of primitives. We, instead, must define an array of vertices, an array of texture coordinates and an array of indices. If you're not sure how this works, think of it like this:
A vertex is a 3 dimensional point in space (x,y,z). 3 vertices can make a triangle.
OpenGL ES draws triangles using the indices. Each index points to a vertex. The idea is that you can re-use vertexes for multiple faces (triangles).
Texture coordinates are mapped 1-to-1 with vertices, NOT indices. The value of a texture coordinate is 0 to 1 and should always be a floating point number. The number represents a percentage of distance, starting in the upper left at 0,0 down to 1.0, 1.0 in the lower right, of the texture image to be applied.
The problem is that when applying textures, you basically need to define the same vertex more than once if two different faces connected to it are to be textured starting at two different locations on the texture. My arena texture is like this. I ended up defining 4 vertices and 6 indices for each side. This allowed me to map a specific square of texture for each face, using 4 texture coordinates. It worked very well this way.
Here is the texture I used and here are some screenshots of how things currently look.
The first image is the actual texture that is being applied to both the arena and the rectangle racer. The second image is a screenshot of the rectangle in 3DStudio. The arena is 440 in size, so I will make the racer 30x8x8 so that it will be the right size and I won't have to scale in the game. The third is a screenshot of how the "game" currently looks. The arena is rendered with the racer rectangle sitting in the middle. You can see how that texture applies.
Importing OBJ Files
If you're not lost in 3D land at this point, you may be asking yourself, "How did you get that 3D Studio rectangle into Android OpenGL ES?" Great question. I exported the .obj file and wrote a tool for my game that can import the obj, aggregate the geometry and output a file that looks like this:
Once you have the model data in those arrays, you can easily create byte buffers, set your texture, transformations, etc and render it using GL10.glDrawElements.
Here's the obj importer I wrote. Depending on what you use to export and what options you have set, you may need to tweak it. It's written specifically for the settings I've chosen to use for my models. It may not work right off the bat for you.
For more help working with .obj files, check out Roy Rigg's OBJ File Format page