Skip to main content
GameDev.net gamedev.net
🔒 Locked

[.net] C# Renderloop

Started by Thevenin Nov 3, 2006 at 4:38 PM 22 replies 5.9k views
Original Post
Thevenin
Thevenin
I need a managed (no dllimports/win32 dependencies/etc) render loop for my C# application. Any ideas where I can find one? Or do any of you know of a good one?
krum
krum
Quote:
Original post by Thevenin
... it looks pretty promising, so if no better (managed) loop is known, I'll use it. [smile]


I use a loop very similar to this. Some people poopoo on this loop because they claim it has some kind of interesting memory allocation characteristics that they do not like, as if they never render any memory in other parts of their engine. I call BS on this argument, but to each his own you know... they can run whatever loop they want. :-)
Saruman
Saruman
Quote:
Original post by krum
I call BS on this argument, but to each his own you know... they can run whatever loop they want. :-)

Unfortunately you are utterly wrong so you shouldn't "call BS on this argument". Using DoEvents is the worst possible way to have a renderloop in C# because of all the needless allocations and generations getting bumped in the GC. Although I do want to add that until you actually see this being a problem (which you will in a larger game).. who cares? I say use DoEvents and later on down the road if you profile and find you have a problem you can refactor it.
krum
krum
Quote:
Original post by Saruman
Unfortunately you are utterly wrong


Wrong about what? It does not appear to me that I made any specific statement to be wrong about.



vermilion_wizard
vermilion_wizard
Apprarently DoEvents makes several managed allocations. Basically, this means that the garbage collector fires more often than it would otherwise. Microsoft claims that a generation 0 garbage collection (which is where the DoEvents allocations would be collected) has a performance hit about equal to a cache miss, so this should be nearly unnoticable, at least until you are pushing the limits of what your machine can do.
Saruman
Saruman
Quote:
Original post by krum
Wrong about what? It does not appear to me that I made any specific statement to be wrong about.

When you said "I call BS on this argument". I was just letting you know that it is in no way "BS" and there are memory allocation issues regarding the generational GC.
daviangel
daviangel
Quote:
Original post by Thevenin
I need a managed (no dllimports/win32 dependencies/etc) render loop for my C# application.

Any ideas where I can find one? Or do any of you know of a good one?

Why don't you just use the one that microsoft uses in the latest DX SDK?
There's probably some pretty good reasons for using it.
If not you can dig up and older DX SDK and use the old way microsoft used to do it using doevents.


[size="2"]Don't talk about writing games, don't write design docs, don't spend your time on web boards. Sit in your house write 20 games when you complete them you will either want to do it the rest of your life or not * Andre Lamothe
vermilion_wizard
vermilion_wizard
I don't think there is any (if I'm wrong, someone please tell me).
The way the DX framework does it is by doing a P/Invoke to call the Win32 PeekMessage function. This tells you whether or not there are messages waiting, and if there are, then a DoEvents call is necessary. Otherwise, you can skip the DoEvents call and save a bit on memory and time.
Etherstar
Etherstar
I've always been a fan of the OnPaint() event handler method. You put your game loop inside an override of your Form's OnPaint method, then call this.Invalidate() at the end of the loop right away. A lot of people feel its hackish and ugly, but it gets the job done and I think it actually makes some logical sense going in the OnPaint method. It doesn't have the memory overhead of the DoEvents method.

daviangel
daviangel
Quote:
Original post by Etherstar
I've always been a fan of the OnPaint() event handler method. You put your game loop inside an override of your Form's OnPaint method, then call this.Invalidate() at the end of the loop right away. A lot of people feel its hackish and ugly, but it gets the job done and I think it actually makes some logical sense going in the OnPaint method. It doesn't have the memory overhead of the DoEvents method.

That's the way they do it on the ms coding for fun website here:
This might explain one reason why games almost always use 100% of your CPU even if they don't appear to be doing much. The faster your computer is, the faster this loop will run and the smoother the animation and the synchronization will be.

There is one slight problem with running a tight loop like that, at least in Windows. If you don't allow Windows to check for and process Windows messages and events, your application will be marked as "Not responding" by the operating system. You might have seen this in your applications if you have a loop that runs for a long time. You might also have solved it by putting a call to DoEvents into the loop, which allows Windows to process the events. This can work reasonably well if you know the loop will end eventually, but in this case the loop is the entire game and you need a better way.

The method I have chosen to use for these games is NOT the most efficient (for a full discussion on this under Managed DirectX see the MDX Game Loop FAQ), but it is the simplest, and none of the games covered here needs the more complex method.

[size="2"]Don't talk about writing games, don't write design docs, don't spend your time on web boards. Sit in your house write 20 games when you complete them you will either want to do it the rest of your life or not * Andre Lamothe
cody
cody
I'm using DoEvents() and i cant notice that it is slow. In a big game you have hundreds or thousands of allocations each frame, and a GC run almost each frame. I dont think DoEvents() makes any difference.
Machaira
Machaira
Quote:
Original post by cody
I dont think DoEvents() makes any difference.

Depends on the game.

http://blogs.msdn.com/tmiller/archive/2005/05/05/415008.aspx

Former Microsoft XNA and Xbox MVP | Check out my blog for random ramblings on game development
paulecoyote
paulecoyote
I was going to post Millers loops - but they do the whole dllimport thing - something the OP didn't want to do.
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.
cody
cody
Well, a small game is fast enough anyway, even with DoEvents(). A large game has so many allocations that DoEvents() is no bottleneck.

I think its a micro-optimization that you can do if you have nothing else to do. Its not wrong to do it, but its wrong to say it is necessary for a game or it will be slow.
paulecoyote
paulecoyote
Ricks discussion on different approaches

Ricks Ideal 100% Managed Loop

Benchmarks of different loops

I wonder if there is a better 100% managed loop out there waiting to be discovered yet. Though as it was Tom and Ricks jobs for a while to hunt out such things... I dunno, seems doubtful.

Quote:

protected override void WndProc(ref Message m){    switch (m.Msg)    {        case (int)Win32Message.Paint:            Frame();            break;        default:            base.WndProc(ref m);            break;    }}
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.
Thevenin
Thevenin
I've read Rick's blogs on the subject a couple times now, and I still don't believe his solutions are 'Managed'.
litewarri
litewarri
Quote:
Original post by paulecoyote
I was going to post Millers loops - but they do the whole dllimport thing - something the OP didn't want to do.


Likewise.

I'm just not sure if there's a completely managed render loop that really performs well.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.