[.net] Help with message loop, MDX/C#

Started by
21 comments, last by thezbuffer 17 years, 12 months ago
So, I've been trying to port my game over from C++/SDL to C#/MDX. It's going pretty smoothly, but I'm encountering problems now, I think. I don't want to use Application.Run() to run my application, I'm using an object-oriented stack-based method for managing gamestates and input and such, so that's a no go. I've been taking a look at this article http://www.codeproject.com/cs/media/ManagedRenderLoop.asp?df=100&forumid=198963&exp=0&select=1426549 for some guidance, and I'm not quite sure if that's what I'm looking for. Firstly, I fail to understand how putting the game loop in an idle event increases performance... wouldn't the game lag if the user was moving their mouse across the screen or something? secondly, my game loop is set up like this: while( looping ) { Application.DoEvents(); HandleInput(); Render(); } And I can't get more than 65 or so FPS, so I'm assuming it's locked. Is there something I can do to unlock the framerate? This all seems like a terrible pain in the rear end, I hope I'm just not understanding something and that it's really not this difficult :/
Advertisement
that is the normal way to do it.

The 'idle' event gets fired when the message queue is empty, so it's not really 'idle', more 'about to go idle'. So acting on it by rendering (and repeated rendering until there is a message to be dealt with) is pretty much as high performance as you can get.

65 fps sounds like you have v-sync enabled. Either that or your frame rate counter is broken :-)
Quote:Original post by nsto119
Is there something I can do to unlock the framerate?

Yep, just set the PresentParameters property PresentationInterval to PresentInterval.Immediate.
[s]--------------------------------------------------------[/s]chromecode.com - software with source code
Quote:Firstly, I fail to understand how putting the game loop in an idle event increases performance... wouldn't the game lag if the user was moving their mouse across the screen or something?


That was my first impression too, but it works like a charm. Because you stop rendering for a few millissecs to handle messages (using the AppStillIdle 'trick'), there's absolutely no lag in the user input (but maybe I'm just slow [wink] ).

In this recent thread you'll find a somewhat better explaination, but the OnIdle/AppStillIdle loop is better since it does not require any extra allocations/collections/wrapping around Window Messages. This means it comes with a minimum of overhead, only yielding to messages/events when there actually are some to process.

Hope this answers your question :)
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
If using C#/MDX, I would recommend using the DXUT toolkit ("Framework") that comes with the Empty Project that you can get from the DirectX Sample Browser. It takes care of device handling for you, and calls you back to "step" and "render" your application.
enum Bool { True, False, FileNotFound };
The SampleFramework also uses the OnIdle/AppStillIdle loop btw, so that would mean it's the 'official' way to do it. Although I've used the SampleFramework quite extensively, I'd recommend coding your device handling and looping yourself.

The framework is great to get things done quickly (and the GUI, Timer etc are good components to reuse), but it has quite some overhead and it doesn't always work as well or staightforward as it should IMO. If you have the time and are comfortable with it, I'd go for coding things from ground up yourself.
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
maybe I'm still misunderstanding something... but wouldn't something like this:

while( running )
{

if( !peekmessage( ... ) )
{
Application.DoEvents();
}

OtherStuff();

}

give the exact same performance, and make it easier to do framerate-indepentant tasks? I'm finding it rather silly that this kind of hack is required to get the best performance.
Quote:Original post by nsto119
maybe I'm still misunderstanding something... but wouldn't something like this:

while( running )
{

if( !peekmessage( ... ) )
{
Application.DoEvents();
}

OtherStuff();

}

give the exact same performance, and make it easier to do framerate-indepentant tasks? I'm finding it rather silly that this kind of hack is required to get the best performance.


A lot of it is because Application.DoEvents() allocates memory every time, which increases the frequency of garbage collections. Using the idle loop actually makes few or no allocations as part of the loop itself.
[sub]My spoon is too big.[/sub]
Here's the history of the Managed DirectX Render Loop with all relevant links.
ZMan
no no no no no no no no no

DO NOT USE: Application.DoEvents

Unless you want to have memory problems, performance issues, and overall beat on the GC for no apparent reason.

This topic is closed to new replies.

Advertisement