We had a snow day from work today, which prompted me to update Winter Simulator. Plus I can link to it in the Android Market now that it is finally web-accessible. Changes were minor, adding on-screen controls and icons. I suspect some people tried the previous version, could not get it to do anything cool, and immediately removed it from their devices. Now it's pretty obvious what it can do as long as people poke at the visible icons.
I would also like to elaborate on the porting process, having brought several of my old OpenGL 1.x/GLUT demos to Android NDK.
Getting a skeleton application working went relatively smoothly, working from the documentation and hello-jni example. The source to Winter Simulator can be explored here. The Java portion does minimal work to set up an OpenGL viewport and then forwards GLUT-like events to the C++ part. I reused essentially the same Java code for several projects, now. In Gingerbread I will supposedly be able to create C++-only applications, but I don't want to limit distribution to only phones with the latest OS, and this was easy enough.
My biggest problem was the difference between the version of OpenGL I had been using and OpenGLES. It was some relief when I realized OpenGLES 1.0 existed, as it shielded me from having to completely redo all of my code to use shaders and my own matrix code.
Things that failed to build included:
- All of the drawing code. I didn't have GLUT solids. I didn't have GLU quadrics. I used both heavily.
- Everything STL-related. I didn't have STL.
- I had only glColor4f, not glColor3f. Fog was different. There were a handful of other things that I just had to change slightly.
I addressed the simple things and did the more complicated things one at a time.
For all drawing code, I had previously hard-coded immediate-mode commands to do most of what I wanted, often using GLU and GLUT primitives to assemble complex shapes like trees and cabins out of cylinders and cubes. I looked into either libraries available for Android or grabbing GLU and GLUT code to run on the phone. Neither appealed to me, so I ended doing something quite strange.
I pasted all of my drawing code into a python script and started implementing missing methods. The syntax use between my C++ code and Python was close enough that I didn't have to make many changes to get it executing. The most annoying part was stripping the trailing f off of floating point constants. I then naively implemented all of the functions I needed to support my drawing code. I made all of the immediate mode GL commands generate vertex buffer data and output a C++ source file with big blobs of data and the code to draw that data. I implemented the basic solids I needed by drawing them out on paper and making slow Python code to generate the triangles. The code didn't need to execute efficiently. It was a one-time process and generated relatively efficient vertex buffers.
That all took some effort, but it was quite easy to approach incrementally, and the end result is just what I wanted.