iCauldron3D Week 3
Lots of progress was made over the past few weeks. The first week went fast, as I already had a number of things in place; mesh format, loader, animation format and loader along with complete skeleton based skinned mesh animation system. Along with the mesh loader I had already built in zip7 support for compression. The final step in adding in mesh support was to make them VBOs. I have to say I really enjoy programming on the iPhone. I've always loved embedded devices and the challenges they bring.
Week two I didn't get as much done, as I was away for 3 days, but still managed to get some things done and keep on track. During the second week it was time for base camera controls and frustum culling. I was able to use most of the camera code from previous projects so it helped to speed things along. I then implemented a 6DOF camera. Next was calculating the frustum and storing it for culling and adding support in for bounding box, spherical and simple box culling. I chose to use spherical culling for scene objects keeping the checks light and fast. Now with frustum culling in place, next was a need for scene management, in which I chose to use an Octree system. Scene objects are loaded into an Octree and just a simple box culling method can be used on the Octree to see if it's visible or not. If not visible then any objects inside assigned to it do not need to be checked for culling, again saving some CPU time. With this in place a scene of 60,000 polys was easy to handle. This is one of the levels for iKrabbit that has been seen in previous screen shots, it's a 2.5D view with enemy AI, animated main character and mounted weapons. On generation 1 device iPod I was getting 45 FPS and on generation 3 60FPS.
Next came sound. Instead of re-inventing the wheel, I was really enjoying using CocosDenshion previously, so I brought that over from Cocos2D which was written by Steve Oldmeadow. Great lightweight objective-c wrapper around openAL. As well João Caxaria supplied a SimpleAudioEngine to use with it. Next was a memory manager written by Paul Nettle. Great tool and excellent for watching memory and keeping those nasty leaks away. It's only enabled during debug builds.
Week 3. First I brought over our SQLite3 tools, used for saved games, player stats and a prefab system currently in the works. These routines have been used over the years in various projects I've worked on and are at the heart of our Database File System. I haven't decided whether to bring the DBFS into iCauldron3D yet, but it's still early.
Now it was time to go 3D. First I needed an environment in which I could drop a character in, attach a 3rd person camera to and run about. So I figured let's use that Octree to create a terrain system. So for the past two days I've been playing with the terrain system, enabling collision, character control and so forth. I tested using TRIANGLE_STRIP terrain and just TRIANGLES based terrain. Reading a heightmap is straight forward and even creating a VBO terrain. As you can imagine a straight TRIANGLES based terrain renders quite slow - around 20 FPS for a 512x512 heightmap. TRIANGLE_STRIP renders quite fast and I can just brute force render the entire terrain stored as a VBO. A 512x512 heightmap only took up 1M of RAM and rendered fast at 50 FPS on a generation 1 device, using a step of 16. This means the terrain is generated every 16th pixel of the heightmap. At a step of 8 the FPS was down to 40 and at 4 the FPS dropped to about 20 - 30. This seemed like a bit of waste though, as you can only see sections of the terrain at any one time. So the next step was to put the terrain into an Octree system. Since TRIANGLE_STRIP is a little more tricky when dealing with slicing it up into an Octree system, I went with TRIANGLES first.
This is a 512x512 heightmap with a single 1024x1024 PVR texture. The yellow lines are debugging lines to see the Octree in action. The octree can be set to a maximum poly limit per oct node, as well the maximum allowable splits. This shows 200 poly limit with a maximum split of 4. Now a straight TRIANGLES based terrain was just as fast as a TRIANGLE_STRIP based terrain. This is using a step of 8 and yields 42FPS.