Managed DirectX Render Loop

I'm sure this question has been asked a million times, but what is the current thinking about the best render loop for Managed DirectX

I found an article on Rick Hoskinson's blog where he suggests overriding WndProc (http://blogs.msdn.com/rickhos/archive/2005/03/30/403952.aspx) and claims it's more efficient than the commonly used DoEvents and Application.Idle methods but I recently downloaded the April 2006 SDK and notice that the samples still use DoEvents. Also I tried using the WndProc method in a game of mine and noticed that in windowed mode it doesn't 'play nicely' with other windows apps, dragging the window for example is very unresponsive. Is it worth using multi-threading for the game loop to maintain responsiveness in windowed mode is it better to keep things simple

Any thoughts experienced Managed DirectX game programmers have on this would be appreciated since I'm a beginner in this area (not programming as a whole, just game programming).

Thanks,

Colin


Answer this question

Managed DirectX Render Loop

  • hayek85

    I totally agree with TheZMan here. You can pick the one that suites you best. When it comes time that you want to switch, make sure that the switch you make has a purpose. I am currently using the Idle approach and it's working pretty good for me.

    Last but not least, have fun :D

    I hope this helps.
    Take care.


  • HopeDreamsComeTrue

    Yes, getting multi-threading to work correctly is difficult. But once it's done, it works well and is easy to debug. I avoided most multi-threading issues by placing the render code in the same thread as the Windows Forms GUI. Only the Present() function is in a separate thread, since that's the only function that blocks. You can download my solution here:

    http://gosub.com/OpenSource/DirectXControl/DirectXControl.htm

    Forget about the efficiency of the different methods. Except for the Present() function which can block your thread for as long as it takes to draw a frame, there's negligible difference. A Windows Forms timer works fine. Watch out because some methods won't update your Window when there's a modal dialog on top.

    -Jeremy



  • Duckboy

    The 'tutorials' in the SDK use DoEvents. The main SDK samples use the .Idle method - its buried inside the dxut framework code.

    What do you mean by unresponsive All the apps I have with OnIdle don't affect any other apps.

    Nothing has changed since Ricks posts - the whole history is here http://www.thezbuffer.com/articles/185.aspx

    To be honest, and this is my opinion, its not worth worrying about unless you belive you are going to be writing Halflife 3 in managed code. Just pick one you are comfortable with and use it. When the time comes to optimize you will find algorithm changes and DirectX common sense give you far more pay back than the render loop. I start all my projects with the dxut framework and then I don't have to worry about this and many other things. But if you want the best - use ricks final one (which should be the same as in dxut).

    One other thing to consider when you read Ricks numbers. His empty render loop is timing in at around 5E-8 for the best and 5E-5 for the worst. Wow you say thats a 1000 times increase - surely this will improve my game no end. But thats the fun of statistics.

    Think about it this way - If you get your game to run at 100fps (nice target to aim for) then this means your frame time will be 1/100s or 1E-2. So the advantage that Rick's loop gives you is 5E-5 - 5E-8 = approx 5E-5 = 1/100000s. So your render loop running at 1/100s per frame just speeded up to 1/100s - 1/100000s. which will give you an extra frame every 100,000 frames of your game which at 100fps is 1000s or 16 minutes. Changing the render loop gives you an extra frame every 16 minutes! Not exactly the 1000 fold increase you thought.

    So maybe the REAL reason to avoid the OnIdle loop is becuase of the huge memory overhead Well memory allocation is very very fast in .Net so lets not worry about that for now. But it has to be GC'd away right Correct but since all the memory is used and then thrown away this will always get caught by a GC0 and that GC0 is probably what costs the extra 5E5 seconds. (Note I've been told that there was some kind of leak in the DoEvents in .Net 1.1 which I've never been able to repro so this would be a valid reason to avoid DoEvents). However extra memory allocations will increase the chance of GC1's happening but this depends on lots of variables. Use perfmon to look at how little time managed apps actually spend in GC.

    The bottom line is that for beginners it really doesn't matter. Choose the on Idle becuase it is the best but feel happy with DoEvents if you are comfortable with it or you don't want the interop stuff.

     



  • Shady9399

    Oh and to your other question - avoid multi threading unless you have a very, very good reason. DirectX has to be put in a special mode to work in a mutlithreaded envionment which has performance implications and in general Miltithreaded programming is much harder to get right and debug.

  • Managed DirectX Render Loop