Posts Tagged ‘netbook’

Cityscape – update 5.1

Friday, May 15th, 2009

So, yeah. I figured out why it didn’t work on my NC10, and it’s for reasons I’d hoped I wouldn’t have to worry about just yet.

See, XNA and DirectX like to pretend that all graphics hardware is equal and can all do the same things and that. And it does quite a good job, so long as all you want to do is draw a few boxes, which is, uh, what we’ve been doing so far. Unfortunately, not all graphics hardware is equal, and actually, there’s some fairly big differences between them.

For example, index buffers. Index buffers are simply a list of numbers that represent indexes into your vertex buffer. You can pick between two formats – 16-bit and 32-bit. With 16-bit, you’re restricted to a maximum vertex index of 2^15, or 32,768 (because, for some reason, they’re apparently signed values, even though a negative index makes no sense). A 32-bit index buffer gives you indices all the way up to 2^31 about 2 billion – far more than you’re likely to need. Previously, I’ve been using 16-bit index buffers, as my vertex buffers have been small and so I didn’t need to capacity of a 32-bit buffer. However, with the change to one single, huge vertex buffer, I needed more than 32,768 vertices and thus switched to a 32-bit index buffer.

Unfortunately, the Intel drivers (the vertex shadey part of the equation actually happens in software on Intel chipsets, although they do have hardware pixel shader support) don’t seem to support 32-bit index buffers. I can create it, stick my indices into it and even successfully call DrawUserIndexedPrimitives<> – but nothing appears onscreen. Culling the number of buildings and using a 16-bit vertex buffer means it works fine.

Again, there are things I can do that will help this – split across several 16-bit index buffers, for example – and it’s actually not necessarily the most efficient thing to render using a single, massive vertex buffer, either: but there’s some optimisations I want to do later than will probably allow me to switch back to using 16-bit index buffers anyway, so for the moment, I’m sadly just going to ignore my little NC10 and stick to developing on machines with more grunt. Ah well.

Cityscape – part 5

Friday, May 15th, 2009

Get a load of this:

See that? That’s a 41×41 city, with 4 boxes per building – a whopping 80k polygons in total – running at our nice full 60fps. That’s over twice the polygon budget of the best of our previous versions, and dramatically more frames per second. How is such dark magic achieved?

Well, remember what we talked about last time? How graphics cards are much happier if you just give them a load of polygons and let them render them without interruptions? That, in a nutshell, is exactly what I’ve done here. Rather than rendering the buildings one at a time in a loop, we take advantage of the fact that buildings basically don’t move that often, and batch them all up into one big array as soon as they’re built. Then, instead of having to loop through a whole bunch of buildings, we just render the one buffer – much better.

Code-wise, we’ve had to do a bit of refactoring here – Buildings are no longer XNA GameComponents, and instead we’ve got a BuildingBatch DrawableGameComponent to handle that side of things for us. We create our buildings, add them to the BuildingBatch, then tell the BuildingBatch to update its geometry – whereupon it iterates through its collection of buildings, grabs their geometry and stuffs them all up in a single vertex/index buffer.

Inevitably, there’s some tradeoffs: by doing our heavy lifting upfront, we limit the amount of stuff we can do once the game is running. So, there’s no easy way to do, say, object culling or dynamic level of detail using this sort of scheme – the time taken to copy all the buildings into the batch buffer is about 150ms – not long, but much more than we’ve got available if we’re trying to render 60 frames a second. And as our buildings get more and more complex, we’re inevitably going to hit an upper limit for which this approach also no longer works – but I’ve got some plans for how to deal with that, too.

Additionally, our buildings are all looking very uniform – as there’s no way to change shader parameters between each building, there’s no way to, say, pass in a custom colour modifier to liven things up a bit – but again, there are ways around this that I’ll talk about at some point later on.

We’re up to bzr revision 14 now – and for some reason, this latest version doesn’t work on my NC10. I am investigating why and should hopefully have a fix soon.