peekmessage while vs if (main/game loop)

Started by
11 comments, last by vstrakh 7 years, 6 months ago

Hi all,

Can someone freshen up my memory on this one?

In my d3d9 engine I've Always had a main/ game loop like this:


	bool run = true;
	
	while(run)
	{
		_mainApp.mInput.UpdateKeys();
	
		while(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
			if(msg.message == WM_QUIT) run = false;
		}
		_mainApp.mTimer.Update();

Currently I'm starting from scratch with my new d3d11 engine, and during learning d3d11, I've found this other way:


	while(msg.message != WM_QUIT)
	{
		if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))			// WHILE ???
		{
            TranslateMessage( &msg );
            DispatchMessage( &msg );
		}
		else
        {	
			//mTimer.Tick();

			if(!mAppPaused )
			{
				CalculateFrameStats();
				UpdateScene(16.67f); //mTimer.DeltaTime());	
				DrawScene();
			}

Is there a performance penalty/ advantage on either one of them compared to the other?

Using 'if' from a 'simple viewpoint' sounds best, because you then only do something if there's a message. With 'while' it sounds like waiting till a message occurs.

Any input/ pointers are appreciated.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement

Imagine you render scene with vsync turned on.

If you go with 'if' implementation, you will process single input event per rendered frame.

But there will be lots of events, especially when mouse moves. If you will process only one event, render frame, wait for 16ms (vsync on), then with simple mouse movement you will create some work for many seconds upfront. Scene update will lag to the point where app will become totally unresponsive.

So you must go with 'while' loop, processing all inputs before you start rendering.

With 'while' it sounds like waiting till a message occurs.

You don't wait for events with PeekMessage(), you would wait with GetMessage().

Just in case vstrakh's answer isn't clear, first one is right, second one is wrong (it will process only one event per frame).

Thanks guys, clear. I can continue with my nice new engine :)
Will keep you posted

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

and during learning d3d11, I've found this other way:

Just in case vstrakh's answer isn't clear, first one is right, second one is wrong (it will process only one event per frame).

so, what does that tell you about the quality of the example dx11 code you're learning from? its obviously not real world code, nor has it ever been tested, otherwise they would have caught the fact that it doesn't even fricking work. i'm not saying all the code is BS, but keep your eyes peeled. example code tends to usually be about 90% correct, with the other 10% being whacked stuff like you found in that dx11 code.

caveat emptor, and you get what you pay for.

EDIT: its actually worse, because they didn't catch the error by inspection - which is entirely possible - and should have occurred before any testing, heck it should have been caught by inspection before they even compiled. does the tutorial you're using come with sample code? or just snippets? does the sample code compile at max warning level with no warning or errors? IE will it even compile, or is it just some person posting some "almost code" pseudocode on a website?

i've run into these issues even with supposedly high quality tutorials such as rastertek.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

@Norman barrows: the book (D3D11 Luna) focusses on learning, not performance.

So you're right about not wanting to adopt everything directly into say a d3d11 engine.

The resulting loop, all working fine:


int CAppl::Run()
{
	MSG msg = {0};
	mTimer.Reset();

	while(msg.message != WM_QUIT)
	{
		while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
            TranslateMessage(&msg);
            DispatchMessage(&msg);
		}

		mTimer.Tick();

		if(!mAppPaused )
		{
			CalculateFrameStats();
			UpdateScene(mTimer.DeltaTime());	
			DrawScene();
		}
		else
		{
			Sleep(100);
		}
    }
	return (int)msg.wParam;
}

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

@Norman barrows: the book (D3D11 Luna) focusses on learning, not performance.

I wouldn't consider that "performance"; I'd consider it "getting the basics right". Put it this way: if tutorial code that I expected to learn from was actually teaching me fundamental bad practices, I'd be mightily annoyed at the tutorial. I should demand no less of a professionally written book.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

The resulting loop, all working fine


It won't work if you get a WM_QUIT message followed by some other message in the same frame. (That's why there was the run = false statement in the first version.)

the book (D3D11 Luna) focusses on learning, not performance.

it would seem it doesn't even focus on functioning correctly at all, much less performance.

personally i've always had the impression that Luna is one of these folks who translates DX docs into books for profit. IE "can't do, so they teach". Has the guy ever made a game?

strange that his works tend to be so well regarded when it would appear he can't even write a message loop correctly.

but enough perfectionism.

follow his code. anything that doesn't work, simply check it against a second source. that's what i always do. eventually between the various sources and your own knowledge, you'll get all the bits and pieces correct.

PS if a book doesn't come with full source that compiles and runs correctly straight out of the box, its a bad omen.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

@Kylotan: thanks, fixed that. See the result below.

@Norman: the book explicitly mentions that it's for learning purposes of d3d11, I don't believe things like this make the D3D11 book from Frank Luna less valuable. I believe lot's of people learned the d3d11 basics from that book.


int CAppl::Run()
{
	MSG msg = {0};
	mTimer.Reset();

	bool run = true;
	while(run)
	{
		while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
            TranslateMessage(&msg);
            DispatchMessage(&msg);
			if(msg.message == WM_QUIT) run = false;
		}

		mTimer.Tick();

		if(!mAppPaused )
		{
			CalculateFrameStats();
			UpdateScene(mTimer.DeltaTime());	
			if(!DrawScene())
			{
				MessageBox(NULL, err_render.c_str(), err_windowtext.c_str(), MB_ICONERROR);		
				return(int)msg.wParam;
			}
		}
		else
		{
			Sleep(100);
		}
    }
	return (int)msg.wParam;
}

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement