Win32 constant rendering

Started by
9 comments, last by Extrarius 15 years, 5 months ago
I setup my window procedure, and the window loop is:

while(GetMessage(&msg, NULL, 0, 0) > 0 && !g_bExit)
{
	Display(60); // calls openGL rendering function at 60fps
	TranslateMessage(&msg);
	DispatchMessage(&msg);
}

can someone tell me what's keeping Display() call from running constantly.. Like it stops somewhere in the loop and comes back in a very non-synced timing..
Advertisement
GetMessage blocks until there is a message available. You probably want to use PeekMessage, but not exactly like that... more like this:

while(!g_bExit){    while (PeekMessage(...))    {       TranslateMessage(...);       DispatchMessage(...);    }    Display(...);}


Kind of, anyway...
Okay. I did that.
Now it certainly runs through, as I can see the increase in processor usage.

But now there comes another problem..

When it executes, everything just freezes. And there's hourglass icon on cursor.

edit: which doesn't make sense, cause there's a 7% (max) CPU usage..

[Edited by - experiment on November 5, 2008 4:46:16 AM]
Quote:Original post by experiment
Okay. I did that.
Now it certainly runs through, as I can see the increase in processor usage.

But now there comes another problem..

When it executes, everything just freezes. And there's hourglass icon on cursor.
Can we see some code? What does the debugger tell you the application is doing?

Did you put some sleep() in your Display() function to insure the message loop will not run like crazy?

Because if GetMessage() blocks until there is a pending message, PeekMessage() returns immediatly even if there is no message. So, if you do not add any sleeping or yielding to the loop, it will monopolise all the cpu.

If you want to render at a particular fps, you may try:
- to add a sleep in your loop,
- to use a timer and call Display() only when you received the timer message,
- or make something more clever in your Display() function that use current and previous time to calculate an adaptive sleep to a really stable fps.

this is the display func:
void Display(DWORD fps){	static DWORD dwLastFrameTime = 0;	DWORD dwCurrentTime = timeGetTime();	DWORD diff = dwCurrentTime - dwLastFrameTime;	if (diff < (1000/fps))		return;	dwLastFrameTime = dwCurrentTime;	glClearColor(0.7f, 0.7f, 0.7f, 1.0f);	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glLoadIdentity();	// View ----------	gluLookAt(		g_jEditorCam.position.x, g_jEditorCam.position.y, g_jEditorCam.position.z,		g_jEditorCam.target.x, g_jEditorCam.target.y, g_jEditorCam.target.z,		0.0f, 1.0f, 0.0f);	glMultMatrixf(g_jViewMatrix.m);	jDrawAxesOGL();	g_jScene.render((float)diff/1000.0f);				SwapBuffers(hDC);}


and this is the main func:
int WINAPI WinMain (HINSTANCE hInstance,					HINSTANCE hPrevInstance,					LPSTR lpCmdLine,					int nShowCmd){	// Enable run-time memory check for debug builds.#if defined(DEBUG) | defined(_DEBUG)    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );#endif	WNDCLASSEX wcx;	HWND hwnd;	MSG msg;	HGLRC hRC;	wcx.cbSize			= sizeof(WNDCLASSEX);	wcx.style			= CS_OWNDC;	wcx.lpfnWndProc		= WndProc;	wcx.cbClsExtra		= 0;	wcx.cbWndExtra		= 0;	wcx.hInstance		= hInstance;	wcx.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));	wcx.hCursor			= LoadCursor(NULL, IDC_ARROW);	wcx.hbrBackground	= (HBRUSH)(COLOR_WINDOW);	wcx.lpszMenuName	= MAKEINTRESOURCE(IDR_MYMENU);	wcx.lpszClassName	= g_szMainClassName;	wcx.hIconSm			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON_SM));	if(!RegisterClassEx(&wcx))	{		MessageBox(NULL, "Window class registration failed", "Error",			MB_ICONEXCLAMATION | MB_OK);		return 0;	}	hwnd = CreateWindowEx(		WS_EX_CLIENTEDGE,		g_szMainClassName,		"J-Editor v1.0 (prototype)",		WS_OVERLAPPEDWINDOW,		0, 0, 800, 600,		NULL, NULL, hInstance, NULL);	if(!hwnd)	{		MessageBox(NULL, "Window creation failed", "Error",			MB_ICONEXCLAMATION | MB_OK);		return 0;	}	EnableOpenGL(hwnd, &hDC, &hRC);	std::ofstream ofile("debug.txt");	ofile << "Debug session file\n";	ShowWindow(hwnd, nShowCmd);    UpdateWindow(hwnd);	/*while(GetMessage(&msg, NULL, 0, 0) > 0 && !g_bExit)	{		TranslateMessage(&msg);		DispatchMessage(&msg);	}*/	while(!g_bExit)	{		while(PeekMessage(&msg, hwnd, 0, 0, 0))		{			TranslateMessage(&msg);			DispatchMessage(&msg);		}		Display(60);	}	DeleteAllTextures();	DisableOpenGL( hwnd, hDC, hRC );	g_jScene.reset();	g_jScene.resetNx();	ExitNx(g_jScene.PhysicsSDK, g_jScene.gScene);	DestroyWindow(hwnd);	return msg.wParam;}


and this is the debug output:
Quote:'J-Editor02.exe': Loaded 'C:\Documents and Settings\Jin\My Documents\Visual Studio 2008\Projects\J-Editor02\Debug\J-Editor02.exe', Symbols loaded.
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\opengl32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\secur32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\user32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\glu32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\ddraw.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\dciman32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\comctl32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\PhysXLoader.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\iphlpapi.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\ws2_32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\ws2help.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\NxCooking.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\winmm.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcp90d.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcr90d.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\imm32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\serwvdrv.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\umdmxfrm.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\MSCTF.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\version.dll'
'J-Editor02.exe': Unloaded 'C:\WINDOWS\system32\version.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\MSCTFIME.IME'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\ole32.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\nvoglnt.dll'
'J-Editor02.exe': Loaded 'C:\WINDOWS\system32\mcd32.dll'
'J-Editor02.exe': Unloaded 'C:\WINDOWS\system32\mcd32.dll'


I wanted to get a screenshot (Print Screen SysRq - key), but it doesn't seem to be giving a damn..

While on the other hand, I can go do something else without any interference. (switch through other windows, and they work fine)
Quote:Original post by experiment
and this is the main func:
*** Source Snippet Removed ***
You need to pass PM_REMOVE as the last parameter to PeekMessage() or else the messages aren't removed, so you'll end up in an infinite loop.
Quote:Original post by experiment
When it executes, everything just freezes. And there's hourglass icon on cursor.


Possibly a problem with your WindowProc... did you call DefWindowProc...??

Quote:Original post by Evil Steve
Quote:Original post by experiment
and this is the main func:
*** Source Snippet Removed ***
You need to pass PM_REMOVE as the last parameter to PeekMessage() or else the messages aren't removed, so you'll end up in an infinite loop.


Yup.. That did it.. Thanks!

Although the Display is still lagging, but at least now it's timed and isn't stopping. ->edit: It's cause of the time calc. inaccuracy.

PS (for future resumes): I also needed to pass NULL instead of handle to the main window, or else the dialogs (other windows) don't work: PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)
Quote:Original post by experiment
Yup.. That did it.. Thanks!

Although the Display is still lagging, but at least now it's timed and isn't stopping. ->edit: It's cause of the time calc. inaccuracy.

PS (for future resumes): I also needed to pass NULL instead of handle to the main window, or else the dialogs (other windows) don't work: PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)


Yes, because that lets you peek at messages for your entire application, rather than just for the specific window whose handle you passed in.

This topic is closed to new replies.

Advertisement