One lesson I learned when initially moving from OpenGL to D3D was that techniques that worked well in OpenGL don't necessarily work well in D3D. Now that I'm back working with OpenGL, it's an interesting experience to be learning that the reverse is also true. Of course it makes sense that this is the case, and you don't (and shouldn't) even have to think about it.
A major stumbling block over the past few days has been the issue of dynamic light updates. This was a critical engine issue because the RMQ folks have maps which are positively swamped in animating lightstyles, and I want to give them the ability to exploit this to the utmost. The world looks active and alive, and this adds so much atmosphere to the whole experience. You feel as if you're moving through a real place (the fact that it's a terminally fucked-up real place only adds to the sense of menace this creates).
Trouble is that it wasn't running well. At all. The engine was hitching and stalling, framerates were see-sawing wildly back and forth between the kind I wanted (steady higher than 72) and the kind I definitely did NOT want (think of a number below 20 and start subtracting from it), and movement and interaction with the world was jerky and awkward. Total mood killer.
The really annoying thing was that the very same technique in DirectQ worked perfectly, and gave ultra smooth performance with none of the issues I had experienced. OK, so they're different APIs, but at the end of the day it's all lines of code and silicon on a chip - the API should be largely irrelevant.
So why was DirectQ so fast and RMQEngine not?
With D3D you need to shove data to the GPU in large batches, and the GPU will love you for it, and reward you with fast and smooth performance in demanding scenes. With OpenGL that is also the case - most of the time. One place where it's different is the case of updating dynamic textures at runtime.
This is where you need to step back and start challenging what you know. In this case I "knew" that I was doing it "right", but I just wasn't getting the kind of performance I wanted. After bashing at it for two days, trying out various techniques (pixel buffers, uploading with sizes as multiples of 4, double-buffering textures, etc) with nothing working it became obvious that it was time for alternative techniques.
I decided as a test to see how the updates worked if I used lots of small updates instead of very few large ones. This totally contradicts everything I considered to be common sense here, but damn it all to hell, it worked.
RMQEngine is now running faster than all versions of DirectQ prior to about 1.8.4, by the way.
__________________________________________________
Speaking of DirectQ, I'm probably going to release the 1.8.666 final build either tomorrow or the day after. There are a few bugs outstanding but I'm going to leave them be for now: I'm pleased as anything with this codebase now, and consider it a great personal achievement. It has been however a quite intense period leading up to this point, and it's been great for me that the opportunity to jump aboard with RMQ came up when it did.
It will also mean than when I get RMQ in a satisfactory initial state I'll be able to take a short break from it, come back and fix those bugs and do some more work with DirectQ, bringing forward things I've learned from RMQ and make DirectQ even better (I'm fascinated to find out if the same lightmaps trick will apply to it).
DirectQ is still my main thing here and - above all else - it is my engine, where I get to call the shots. That's important. What's also important is to vary your experience and learn new things a little outside of your comfort zone (but not too much!) We should all do that a bit more at times.
Tuesday, July 20, 2010
Fun With OpenGL
Posted by
mhquake
at
11:58 PM
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment