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

Coding sturcture that's easiest to reset the window

Started by dm_3x May 8, 2010 at 1:21 AM 7 replies 1.8k views
Original Post
dm_3x
dm_3x
I'm sure many of you have seen Nehe's opengl tutorial. One feature of his program is how easy to switch from window mode to full screen mode. However, looking at his code, which use PeekMessage, consume 100% of a single core cpu cycle. Which isn't a good idea either, imo. Just wonder if anyone knows whether there is better way to saving more cpu cycle as well as getting the job done. Thanks.
Washu
Washu
Quote:
Original post by dm_3x
I'm sure many of you have seen Nehe's opengl tutorial. One feature of his program is how easy to switch from window mode to full screen mode. However, looking at his code, which use PeekMessage, consume 100% of a single core cpu cycle. Which isn't a good idea either, imo. Just wonder if anyone knows whether there is better way to saving more cpu cycle as well as getting the job done.

Thanks.


It isn't eh? Why is that? If your game is the foreground application then one can assume that the player wishes to interact with that game in an efficient and timely manner.

Mind you, when you don't have the focus then you should perhaps WaitMessage, don't forget to update your timers though [grin].
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
Erius
Erius
Try using a "for" loop instead of a "while" loop.

like so
for (;PeekMessage();){DoStuff();}


Though I'm not sure if that really has any benefit for processing the message queue, but switching to a for instead of a while for the main game loop does stop the program from hogging unneeded CPU time.
Washu
Washu
Quote:
Original post by Erius
Try using a "for" loop instead of a "while" loop.

like so
*** Source Snippet Removed ***

Though I'm not sure if that really has any benefit for processing the message queue, but switching to a for instead of a while for the main game loop does stop the program from hogging unneeded CPU time.


Assuming "DoStuff" does game related stuff, then that loop is a very BAD idea.

There is no reason for a game NOT to take 100% of the CPU time. You may note that all of those fancy AAA titles sure don't mind doing it [grin]. The few cases where it doesn't matter (Tictactoe?) can be written using GetMessage() and WM_PAINT handling just fine.
The traditional message handling loop works just fine for a game...
bool running = true;MSG msg;while(running) {    while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {        if(msg.message == WM_QUIT) {            running = false;            break;        }        TranslateMessage(&msg);        DispatchMessage(&msg);    }    if(running)        DoGame();    //optional wait if you want...    WaitMessage();}
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
Erius
Erius
Hm. I haven't noticed any performance issues and I always use "for" loops for the main loop <.<.

So far, it always scaled with the required amount of power.
If it's trivial stuff I get single digit usage, and if it's something complex the app gets as much as it can.

I'm gonna profile it a bit, gives the trial of AQTime some use :P.
Washu
Washu
Quote:
Original post by Erius
Hm. I haven't noticed any performance issues and I always use "for" loops for the main loop <.<.

So far, it always scaled with the required amount of power.
If it's trivial stuff I get single digit usage, and if it's something complex the app gets as much as it can.

I'm gonna profile it a bit, gives the trial of AQTime some use :P.

If your "DoStuff" method does game related stuff, then you only process ONE message at a time between game updates. Which means that if you move your mouse and around and do keyboard input, you'll rather quickly find that it's quite far behind in the message queue. what with it having to render one frame for each message.

The proper way of handling this is to process all outstanding messages first, then update your game when it is IDLE. Your game does not consume 100% of the CPU from everyone, it consumes 100% of the CPU available to the thread while it is IDLE (that is, no messages pending).
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
Erius
Erius
Ah, yes, of course. Maybe I should have clarified that I don't use a standard loop.

Mine goes like this
for  (;main_window.Active();)		{				time.get_time();		main_window.msgpump();		//DoStuff, includes physic timestepping(Bullet in my case), etc                UpdateThis(time.dt);                UpdateThat(time.dt);                RenderStuffOrSomething();                Etc();	}

The Message loop is a standard loop.
msgpump(){			while (PeekMessage(&message, window, 0, 0, PM_REMOVE)) 	{		TranslateMessage(&message);		DispatchMessage(&message);	}}

game related messages are processed in that loop and the results get pushed onto command stacks which the objects that are interested in those results consume somewhere in the "DoStuff" region.

But yeah, I swapped looptypes for 10k frames each, and the results were pretty much the same.
Some took ~5 ms less in total than before, others more.
the 'hierarchy' of used time stayed the same.

*shrug*
I guess it's a matter of arrangement then?

Edit:
Oh yeah, the for loop again only used 2% CPU time. While the whole thing.
After throwing in a 1million iteration per frame loop where 5 numbers where multiplies, divided and powered, both used 100% after that, but not a big speed difference.
mzeo77
mzeo77
There is plenty of reasons why always use 100% cpu if not needed is bad. Batteri life of portable computers for example. And besides, why do it the wrong way (unnecessary use of 100% cpu) when there is a better way.

Here is link how to sleep while processing messages:
http://blogs.msdn.com/oldnewthing/archive/2006/01/26/517849.aspx

It should be adjustable to a fixed get a fixed framerate step/render loop. (why fixed framerate is a good thing: http://gafferongames.com/game-physics/fix-your-timestep/)

Another way would be to get flipscreen to wait for v-sync before flipping. It should also cap cpu usage.
dm_3x
dm_3x
Thank you for all the good ideas so far. I think I'll try the WaitMessage first and see how things go.

I do have another question about using the PeekMessage. This Microsoft page show us how to process without going to the call back function.

http://msdn.microsoft.com/en-us/library/ms644928%28VS.85%29.aspx#examining_queue

Then I'm not sure how we set up the WNDCLASS.lpWndProc. Because if we set that to NULL, the window won't work at all. I tried to set it to DefWindowProc, pretty much not respond. If someone could put a complete source code from setting up the window to how to use that example correctly, would be the best

Topic Locked

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

Sign in to reply to this topic.