Friday, July 30, 2010

More HLSL/GLSL Fun

I've successfully ported the DirectQ waterwarp to GLSL and now have it running in the engine. DirectQ's version is very configurable with cvars to define the warp speed and scale (they all begin with r_warp so look out for them) but I likely won't be doing this for RMQ as all I wanted was a higher quality version of the classic water warp - something that doesn't look like shit, in other words.

Most of the differences between HLSL and GLSL arise from the underlying different philosophies behind Direct3D and OpenGL. In general I find D3D to be more powerful and closer to the hardware - you ask for something, that's exactly what you get, and if it doesn't exist it blows up in your face - whereas GL has at least one more layer of abstraction between the hardware and the API - you don't always get exactly what you ask for but you'll get something that's likely to work anyway, and if it doesn't exist it will possibly fall back to software emulation. Both are valid perspectives and there are sound reasons in favour of both. I personally prefer the D3D approach as I like to know what I'm dealing with, and am a little uneasy at the vagueness and sense of never quite being certain that comes with GL, but that's just me; other people will be different and that's OK too.

Parts of GLSL are pretty nifty. I now like the shader/program attach/detach model a lot, and it's a reasonably close analog of D3D's FX framework. Not as nice to work with, but not as horrible as my initial impressions led me to fear. The terminology is slightly bizarre though; at the very least I would have chosen "unit" instead of "shader". Reading the ARB docs from the time reveals that there was possibly a hint of pedantry and inverse snobbery involved in the choices here. Sigh. How very unlike OpenGL (sarcasm).

The whole uniform/varying thing is freakish. D3D's approach of just passing structs around seems more sensible. Pixel shader gets the struct that's returned from the vertex shader as a param - simple, sensible, clean. On the other hand GL's built-in gl_Vertex, gl_Position, gl_TexCoord, etc is very much the right thing, although I understand that they're gone from more recent versions.

The quality of the documentation and tools for GLSL is horrible. Tool-wise, nothing with the capabilities of PIX exists and debugging is very hit and miss. GLIntercept is reasonably decent and has been a life-saver, but PIX lets you go so far as to debug individual pixels on-screen at each stage of the frame. It's a joy to use, and an essential tool.

Documentation-wise I could use a proper SDK. Something I can download, install, and have indexed and searchable on my hard disk at all times. With a suite of tools and examples (ones that someone has actually bothered to compile and test would be nice), technical articles, FAQs, and all the other good stuff you need. I'll never complain about the D3D SDK again. It's a sad and shocking fact that the best OpenGL documentation, even today, is still the old MSDN OpenGL 1.1 stuff.

I think that just about wraps up the extent to which I'm going to be using GLSL for the RMQ engine. I could potentially spend the next 6 months implementing the entire renderer in GLSL, fine-tuning and tweaking it along the way, but nothing else would get done. Like I said, improving the water warp quality was the objective here and that's just a bonus feature, and an interlude to give me time to think over a few things relating to what I need to do next. Higher priorities are beckoning.

Till next time!

0 comments: