So, I read this series of articles on building a simple, programmatically generated city. The techniques being used are surprisingly simple and really quite old-school (everything is being done with what amounts to the state of OpenGL about 10 years ago – no shaders, no bumpmaps, no vertex buffers, nothing) – but the results are really rather effective. Anyway, as long-time readers of this here blog will know, I used to be a games developer way back in the day, and I’ve still got a bit of a hankering after 3D graphics programming, so I thought I’d give a similar project a go myself: I freely admit that I’m totally stealing the original idea here, but hey – imitation is the sincerest form of flattery, and that.
Anyway, I’ve been meaning to give all of Microsoft’s shiny XNA/C# tools a proper go for some time now, so this seems like an ideal project. This means I get to mess about with things like shaders, funky post-processing techniques and other modern trickery without having to muck around with all the pain of resource management in DirectX/C++ – this will probably be at the expense of a bit of speed, but hopefully the ability to make use of hardware vertex/pixel processing should make up for this.
I’ve got vague plans that eventually this should have stuff like cubemapped reflections for windows, dynamic level of detail for speedup, atmospheric effects using rayleigh scattering and lots of other exciting things, if I have time. But, first things first: the very first thing to do is to get something up on the screen. In this instance, it’s a hugely exciting texture-mapped cube:
Actually, there’s quite a lot more to this than it looks: to render that, we build an array of texture-mapped vertices with normals, then render it using a custom XNA effect (which, at the moment, contains a very simple pair of vertex and pixel shaders to do diffuse lighting). The light source is fixed to the camera position, and the camera is rotated around the box at the speed of 1 radian/second.
There’s two classes involved here: the XNA Game class, and the Building class, which is derived from the XNA DrawableGameComponent class. When the Game object is Initialize()d, a Building object is created and added to the Game’s Component list. When the Building object is Initialize()d, it calls the AddBox() method, which populates a list of VertexPositionNormalTextures and UInt16s with vertex and index data for a box of the appropriate dimensions, and then copies that data into static arrays (for speed of rendering). A texture and the render Effect are loaded and bound appropriately.
Then, on Draw(), the Game sets up appropriate render states, positions the camera, and calls Draw() on all the child components; the Building’s Draw() calls then sets up the matrices for its Effect, and loops over the Effect’s passes (in this case, there’s only one) calling DrawIndexedUserPrimitive() to render the box.
It’s quite a lot of code to get up and running, but hopefully this setup should mean that progress from here involves rather less setup and skeleton code. If you want to follow the code for this as well, there’s a Bazaar repository at http://bzr.parm.net/Cityscape/ – it’s read only, although obviously you’re entirely free to create your own local branches and tool around with it as much as you like. We’re up to revision 4 at the moment – and the first couple of revisions are slightly broken.
I make no claims about the quality of the code, or even if it’ll work on your machine – it’s a Visual Studio 2008 project, using XNA 3.0; it ought to build in Visual C# Express with a small amount of poking, but I haven’t tried it. It seems to run reasonably well on my poky little netbook (as well as beefier machine with Real 3D Hardware) at the moment, so with a reasonably recent machine, you should be good to go.
Next step: Make an actual building!