Frozenwounds:I'm not doing anything to the vertex buffer, but changing the vertex format. It's basically the VertexPositionNormalTexture but with colour added in. I've now applied the DrawIndexedPrimitives and got a significant speed gain. However I'm still looking for more.
Have you profiled to see where your bottleneck is now? DrawIndexedPrimitives is pretty much as fast as you get for single models.
Check that you're not changing state too much.
If you draw like this:
for each model
set renderstate
set material settings (textures, matrices, etc)
set vertex descriptor
set vertex buffer
set index buffer
begin effect
draw indexed primitives
end effect
Try to reduce state changes:
set renderstate
set vertex descriptor
set vertex buffer
set index buffer
set common material settings
begin effect
for each model
set unique material settings
effect.commitchanges
draw indexed primitives
end effect
Nothing really special, just the standard technique of pulling constants values out of inner loops.
Some trivial looking changes such as setting the vertex descriptor can be surprisingly expensive.
There may be some pointers here too:
http://forums.xna.com/forums/t/28824.aspx
Frozenwounds:
Also is instancing even possible/relevant when I'm not actually using the model class?
Yeah, instancing is totally a GPU thing. The default Model class doesn't support GPU instancing either, you need to modify it.
Instancing does work best on smaller models, you may not see much improvement. I'd make sure your rendering loop is optimized before looking at instancing.