A high performance, large scale, deformable terrain example for Chipmunk Pro.
MIT License
p=. !http://files.slembcke.net/upshot/upshot_SpacePatrol.png!
"YouTube Video":http://www.youtube.com/watch?v=rb49mke8K2k
h1. Space Patrol
You are a Super Space Ranger with an awesome space buggy. Fortunately you've landed on a really sweet planet with deformable terrain (Wait... what?). You can catch some sweet air or dig around through the ground. You can do whatever you want because you are a Super Space Ranger. Who could stop you anyway?
This isn't really a game per-se, so the controls are a bit of a mashup:
h2. Overview:
This is a Chipmunk Pro autogeometry demo project that is built on top of Cocos2D 2.0. The focus for this demo is to show how to mix Chipmunk Pro's autogeometry to implement very large scale, real-time deformable terrain with Cocos2D 2.0. Unlike the Cloud Bomber example, which deformed the terrain bitmap on the GPU and paid a high syncronization cost to read it back, Space Patrol deforms the bitmap using a CGBitmapContext and then uploads only the changed pixels back to the GPU.
The terrain density texture is 2048x512 (You could go as high as 2048x2048 though). When rendering, this is upscaled by 32x (64x on retina) giving you a fully deformable world that is over 130 screen widths wide. That is a huge world to explore from a measely 12kb PNG density image! Rendering the world is performed by a shader that renders all of the following in a single pass:
Because this all happens in a single draw pass without blending to the framebuffer, it's very fast and can even run at 60fps on an iPhone 4. Another benefit of rendering the entire terrain using a fragment shader is that the terrain can be smoothly morphed without having chunky geometry changes. You can see the effect of this in the video above. It basically looks awesome. :D
h2. How it works:
Chipmunk Pro allows you to trace images (or procedural functions) to turn them into geometry. For Objective-C, it comes with a few handy wrapper classes that make this easy to do. One of them, ChipmunkCGContextSampler, links the autogeometry to a CGBitmapContext. In this way you can perform high-quality, CPU side rendering of the terrain deformations.
Then the ChipmunkCGContextSampler is linked up with a tile cache that breaks the world up into tiles. The geometry for a tile only needs to be regenerated if it is onscreen (or some other rect you specify) and its pixels have been modified. This means you don't need to waste CPU time or memory to process geometry that isn't onscreen.
After drawing terrain deformations into the CGBitmapContext, it marks the drawn areas as dirty rects in the tile cache. It also uploads those dirty rects to the terrain density texture at this point too. This is unfortunately a little slow, making the framerate a little jump when constantly deforming the terrain, but I don't think there is much that can be done about that.
The terrain shader uses the value from the terrain density texture as a threshold to decide whether to draw terrain or the parallax background. If the density was used directly as the alpha, this would look terrible as it is somewhat blurry and upscaled by a huge amount. I used a lookup texture to get a nice threshold for the terrain as well as the thickness of the crust on top. The threshold is perturbed by a second texture to make the crust look more interesting.
h2. Future Enhancements:
There are a few things that could be enhanced in the demo, but I didn't want to waste too much time on it. Maybe I'll come back around and do them later...