Introduction
Several years ago, as part of a big project to replace an aging graph/chart viewer, I wrote a really neat 3D renderer. The idea was the new graph viewer would be built on the renderer and allow viewing of proper 3D charts, with all the nice bits like a perspective transformation and light sources.
This all turned out well, and the renderer allowed different implementations to be plugged in (abstracted behind generic COM interfaces). Around that time 3D graphics were a bit of a hobby of mine (Direct3D 3 was current, and times were grim). After a long night drinking Pan-Galactic Gargle Blasters I worked out how to write a scan-line 'display list' renderer (if you've ever looked into how the old PowerVR hardware works, the concept was similar).
All this was written in Delphi, and as the years (and employers) passed I pondered writing a hobby version in C++, and later C#. DirectX was evolving rapidly though, so there didn't seem much point writing a PC version, particularly since I'd never bothered to work out how to apply textures or alpha blending to surfaces (well I knew how, but never had time).
A couple of days ago I had the crazy idea of making a PocketPC version, and here it is!
Background / Implementation
This is a mixture of a few different projects ported to the Compact Framework:
- A scan line renderer, still unable to do texturing or anything invented in the last 10 years, but at the same time very cool just because it's efficient. It doesn't have (or need) a z-buffer, and it renders each pixel only once. It should be quite straightforward to add texturing or blending.
- A very simple 3D engine, providing some basic constructs for building animated objects. It's designed to represent things with moving bits on them, like a robot whose body moves and each arm moves in relation to that.
- A simple 3D spaceship to spin about. This was from my first attempt at writing a game in C# and Direct3D, a long time before all the nice managed bits of DirectX 9!
Points of Interest
The porting only took a few hours (spread over a couple of days). The first bit was converting the old Delphi renderer into C# (using the full .NET Framework as it's quicker/easier to debug). I tied this together with bits of old half-completed hobby projects. Obviously the Compact Framework gets kicks out of throwing some spanners in the works:
- Good old XML Serialisation again. My previous .NET D3D projects used serialisation as an easy way to persist (and load) primitives (polygons) & vertices to render. Instead I created an XML schema and loaded the model into a pseudo-typed dataset (the CF doesn't support the proper typed
DataSet
s of the full framework).
- Trying to render the image into a back-buffer to blit later to the screen was a real pain. The full Framework has a nice method of the Bitmap class called '
LockBits()
'. Unfortunately the CF designers decided this was one of the things to ditch in favour of footprint (thanks guys). Apparently this will be present in CF 2.0, but obviously I was too impatient for that. What I did was create a MemoryStream
and fill it first with some image headers, and then with my rendered image bytes (from an unsafe byte array). I fed the stream straight into a new Bitmap object and (after a couple of tweaks, like having to make the image upside-down) it worked!
- The demo just rotates and wiggles the spaceship a bit when you move the mouse. The idea is one of you guys will take this project and maybe turn it into something useful. As I still don't have a 'real' PocketPC, I'm not sure how this'll work with the stylus etc. It should do something...