Sunday, November 8, 2009

Thinking about D3D8

I posted a while back about my experiences in porting DirectQ 1.7.3 to Direct3D 8. Since then I have done some more work with this version of the API, and have some things to report.

Firstly is the fact that I successfully resolved the speed issue. As I had commented before, this was caused by mipmaps not working, and the reason why they didn't work was a bad selection of filtering modes. It seems as though D3D9 was a little more forgiving than D3D8 in this respect. It's nice to find and fix a bug in the main codebase in such a manner, and also nice to get D3D8 speed up to par.

Secondly, and quite importantly, I have been working part time on a D3D8 wrapper for OpenGL. The intention is to make it available for use with ProQuake, but it's also potentially suitable for more general use. It's not a full wrapper, but has more in common with the old 3DFX mini OpenGL DLLs in that it restricts itself to the subset of features used by GLQuake (but can be compiled directly into the engine exe). No reason why an enterprising programmer couldn't extend it all the way however, although shaders would require a full parser/lexer/converter implementation which is well outside the scope of what I'm trying to achieve with it. Think more OpenGL 1.3 to 1.4 level and you'd be roundabout there (although I haven't done multitexturing or combines yet).

Performance of this wrapper is actually quite good with GLQuake, easily hitting 100 FPS on a machine that gets 110 FPS with DirectQ. This is with a 2 pass full render of everything, but misses out on RGBA lightmaps and compressed textures. I would guess in an exact like-for-like scenario it would be a very close call.

Bottom line is that it has convinced me that D3D8 is viable. The one issue I had considered a sticking point (lack of being able to set a constant colour at TextureStageState) has turned out to be not so important after all as I pass in an additional D3DCOLOR with each vertex which is either modulated with the texture or left alone (this can be optimized by switching the struct depending on the TexEnv but Quake isn't a graphics pig so it's not too much a big deal).

I'll probably do some further porting tests on DirectQ itself, but any final decision on a full port will be held until I release the current version. There are advantages however, specifically an ability to run on even older hardware, and without the requirement for annoying DirectX updates even on Vista and 7. Since DirectQ itself uses a D3D6 or 7 level of technology (but with the D3D9 API) there's not much to lose by doing this.

Writing this has definitely opened my mind to how weird OpenGL is. I mean really really weird. It's still nice to use, but some of the contortions behind the scenes seem like some very strange design decisions were made, and it's roots as a non-textured gouraud-shaded API that could have had a much more graceful evolution really come forward. Stuff like how the glVertex calls really work (and this isn't an artefact of my wrapper, just read the spec) is quite bizarre.

0 comments: