Pros/Cons of using WM_PAINT for rendering

Started by
9 comments, last by 21st Century Moose 13 years, 6 months ago
Pretty straight-forward,

What is the OpenGL 3.0 way of handling the Windows Window system? (ie creating a
window)

------------------------------

redwoodpixel.com

Advertisement
IMHO:
WM_PAINT for rendering ONLY when you don't have to update continuously: only when events (window messages) occur. Most games have to be updated repeatedly, so you have to render "outside" the message handling loop. So not in WM_PAINT.
The problem with Windows messaging functions is that there is no guarantee of when the message will arrive at your application. So there will definitely be some latency between the time when your window needs to be redrawn and the time when your app gets the WM_PAINT and is actually redrawn. How long that is depends on a variety of factors, many of which are completely outside of the control of your app (some AV software might be hooking and examining all Windows messages for all apps as part of it's heuristics, for example). So what runs fast on one machine might be unacceptably slow on another.

You're better off writing a proper game loop (using PeekMessage instead of GetMessage) and doing your rendering in that.

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

Yeah... i agree... so i currently have a peek message loop implemented, but am not sure how the device context lives through the application.

For some reason my device context gets lost (even with using OWN_DC).

I am running out of ideas as to why this is happening.

When using the WM_PAINT, you get difference DC's throughout your application.

------------------------------

redwoodpixel.com

Post code. Do you store all the handlers during the lifespan of the program (window, device, rendering context) and use them? Do you create the window/device/rendering context in the appropriate order?
RegisterClass(...)MainWindow.hWnd=CreateWindowEx(...);ShowWindow(...);MainWindow.hDC = GetDC(MainWindow.hWnd);PixelFormat = ChoosePixelFormat(MainWindow.hDC,&pfd);SetPixelFormat(MainWindow.hDC,PixelFormat,&pfd);MainWindow.hRC = wglCreateContext(MainWindow.hDC);wglMakeCurrent(MainWindow.hDC,MainWindow.hRC);OpenGLInitStuff();
Ha... your code is unbelievably simplified.

I will refactor mine before i post my mess of code.

EDIT: It's actually not that bad... most of it is from the tuts.

GLuint		PixelFormat;			// Holds The Results After Searching For A Match	WNDCLASS	wc;						// Windows Class Structure	DWORD		dwExStyle;				// Window Extended Style	DWORD		dwStyle;				// Window Style	RECT		WindowRect;				// Grabs Rectangle Upper Left / Lower Right Values	WindowRect.left=(long)0;			// Set Left Value To 0	WindowRect.right=(long)width;		// Set Right Value To Requested Width	WindowRect.top=(long)0;				// Set Top Value To 0	WindowRect.bottom=(long)height;		// Set Bottom Value To Requested Height	fullscreen=fullscreenflag;			// Set The Global Fullscreen Flag	this->m_hInstance			= GetModuleHandle(NULL);				// Grab An Instance For Our Window	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_GLOBALCLASS;	// Redraw On Size, And Own DC For Window.	wc.lpfnWndProc		= (WNDPROC) WndPDummy;// WndProc Handles Messages	wc.cbClsExtra		= 0;									// No Extra Window Data	wc.cbWndExtra		= 0;									// No Extra Window Data	wc.hInstance		= this->m_hInstance;					// Set The Instance	wc.hIcon			= LoadIcon(NULL, IDI_WINLOGO);			// Load The Default Icon	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			// Load The Arrow Pointer	wc.hbrBackground	= NULL;									// No Background Required For GL	wc.lpszMenuName		= NULL;									// We Don't Want A Menu	wc.lpszClassName	= _T("OpenGL");								// Set The Class Name	if (!RegisterClass(&wc))									// Attempt To Register The Window Class	{		MessageBox(NULL,_T("Failed To Register The Window Class."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);		return FALSE;											// Return FALSE	}		if (fullscreen)												// Attempt Fullscreen Mode?	{		DEVMODE dmScreenSettings;								// Device Mode		memset(&dmScreenSettings,0,sizeof(dmScreenSettings));	// Makes Sure Memory's Cleared		dmScreenSettings.dmSize=sizeof(dmScreenSettings);		// Size Of The Devmode Structure		dmScreenSettings.dmPelsWidth	= width;				// Selected Screen Width		dmScreenSettings.dmPelsHeight	= height;				// Selected Screen Height		dmScreenSettings.dmBitsPerPel	= bits;					// Selected Bits Per Pixel		dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;		// Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.		if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)		{			// If The Mode Fails, Offer Two Options.  Quit Or Use Windowed Mode.			if (MessageBox(NULL,_T("The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?"),_T("NeHe GL"),MB_YESNO|MB_ICONEXCLAMATION)==IDYES)			{				fullscreen=FALSE;		// Windowed Mode Selected.  Fullscreen = FALSE			}			else			{				// Pop Up A Message Box Letting User Know The Program Is Closing.				MessageBox(NULL,_T("Program Will Now Close."),_T("ERROR"),MB_OK|MB_ICONSTOP);				return FALSE;									// Return FALSE			}		}	}	if (fullscreen)												// Are We Still In Fullscreen Mode?	{		dwExStyle=WS_EX_APPWINDOW;								// Window Extended Style		dwStyle=WS_POPUP;										// Windows Style		ShowCursor(FALSE);										// Hide Mouse Pointer	}	else	{		dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			// Window Extended Style		dwStyle=WS_OVERLAPPEDWINDOW;							// Windows Style	}	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);		// Adjust Window To True Requested Size	// Create The Window	if (!(m_hDevWindow=CreateWindowEx( dwExStyle,							// Extended Style For The Window								_T("OpenGL"),							// Class Name								title,								// Window Title								dwStyle |							// Defined Window Style								WS_CLIPSIBLINGS |					// Required Window Style								WS_CLIPCHILDREN,					// Required Window Style								0, 0,								// Window Position								WindowRect.right-WindowRect.left,	// Calculate Window Width								WindowRect.bottom-WindowRect.top,	// Calculate Window Height								NULL,								// No Parent Window								NULL,								// No Menu								m_hInstance,						// Instance								NULL)))								// Dont Pass Anything To WM_CREATE	{		// Retrieve the system error message for the last-error code		this->Shutdown();											// Reset The Display		MessageBox(NULL,_T("Window Creation Error."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}		hookWindow(m_hDevWindow);	static	PIXELFORMATDESCRIPTOR pfd=				// pfd Tells Windows How We Want Things To Be	{		sizeof(PIXELFORMATDESCRIPTOR),				// Size Of This Pixel Format Descriptor		1,											// Version Number		PFD_DRAW_TO_WINDOW |						// Format Must Support Window		PFD_SUPPORT_OPENGL |						// Format Must Support OpenGL		PFD_DOUBLEBUFFER,							// Must Support Double Buffering		PFD_TYPE_RGBA,								// Request An RGBA Format		bits,										// Select Our Color Depth		0, 0, 0, 0, 0, 0,							// Color Bits Ignored		0,											// No Alpha Buffer		0,											// Shift Bit Ignored		0,											// No Accumulation Buffer		0, 0, 0, 0,									// Accumulation Bits Ignored		32,											// 16Bit Z-Buffer (Depth Buffer)  		0,											// No Stencil Buffer		0,											// No Auxiliary Buffer		PFD_MAIN_PLANE,								// Main Drawing Layer		0,											// Reserved		0, 0, 0										// Layer Masks Ignored	};		if (!(hDC=GetDC(m_hDevWindow)))							// Did We Get A Device Context?	{		this->Shutdown();								// Reset The Display		MessageBox(NULL,_T("Can't Create A GL Device Context."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))	// Did Windows Find A Matching Pixel Format?	{		this->Shutdown();								// Reset The Display		MessageBox(NULL,_T("Can't Find A Suitable PixelFormat."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	if(!SetPixelFormat(hDC,PixelFormat,&pfd))		// Are We Able To Set The Pixel Format?	{		this->Shutdown();								// Reset The Display		MessageBox(NULL,_T("Can't Set The PixelFormat."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	if (!(hRC=wglCreateContext(hDC)))				// Are We Able To Get A Rendering Context?	{		this->Shutdown();								// Reset The Display		MessageBox(NULL,_T("Can't Create A GL Rendering Context."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	if(!wglMakeCurrent(hDC,hRC))					// Try To Activate The Rendering Context	{		this->Shutdown();								// Reset The Display		MessageBox(NULL,_T("Can't Activate The GL Rendering Context."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}	ShowWindow(m_hDevWindow,SW_SHOW);						// Show The Window	SetForegroundWindow(m_hDevWindow);						// Slightly Higher Priority	SetFocus(m_hDevWindow);									// Sets Keyboard Focus To The Window	this->ReSizeGLScene(width, height);					// Set Up Our Perspective GL Screen    	if (!this->OnInit())									// Initialize Our Newly Created GL Window	{		this->Shutdown();								// Reset The Display		MessageBox(NULL,_T("Initialization Failed."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);		return FALSE;								// Return FALSE	}    this->soundMan.Init();    // load stolen windows sound for now    //this->soundMan.Load("..\\Content\\Sounds\\type.wav", false);    this->AssetMgr->GetSound("..\\Content\\Sounds\\type.wav", false, &this->soundMan);    this->lastTime = timeGetTime();	return TRUE;



and on shutdown, you can see where i get the 1425 error code
if (fullscreen)										// Are We In Fullscreen Mode?	{		ChangeDisplaySettings(NULL,0);					// If So Switch Back To The Desktop		ShowCursor(TRUE);								// Show Mouse Pointer	}		if (hRC)											// Do We Have A Rendering Context?	{		if (!wglMakeCurrent(hDC,NULL))					// Are We Able To Release The DC And RC Contexts?		{			MessageBox(NULL,_T("Release Of DC And RC Failed."),_T("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION);		}		if (!wglDeleteContext(hRC))						// Are We Able To Delete The RC?		{			MessageBox(NULL,_T("Release Rendering Context Failed."),_T("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION);		}		hRC=NULL;										// Set RC To NULL	}	bool Released = ReleaseDC(m_hDevWindow,hDC);	DWORD errr = GetLastError();	if (hDC && !Released) // Are We Able To Release The DC	{		MessageBox(NULL,_T("Release Device Context Failed."),_T("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION);		hDC=NULL;										// Set DC To NULL	}	bool R = DestroyWindow(m_hDevWindow);	DWORD errrr = GetLastError();	if (m_hDevWindow && !DestroyWindow(m_hDevWindow))					// Are We Able To Destroy The Window?	{		MessageBox(NULL,_T("Could Not Release hWnd."),_T("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION);		m_hDevWindow=NULL;										// Set hWnd To NULL	}	if (!UnregisterClass(_T("OpenGL"),m_hInstance))			// Are We Able To Unregister Class	{		MessageBox(NULL,_T("Could Not Unregister Class."),_T("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION);		m_hInstance=NULL;									// Set hInstance To NULL	}		return S_OK;


[Edited by - AverageJoeSSU on October 18, 2010 12:05:40 AM]

------------------------------

redwoodpixel.com

Nope. Pay attention to the order that I posted!

You have to ShowWindow before you get the device. When I did it just like you do, I got very strange and seemingly unrelated bugs. With fonts for example. My code is simplified but that should be just enough.

The order is very important!!
unfortunately moving show window right after create window didnt solve my issue of not being able to release the dc. Thanks for the tips though.

------------------------------

redwoodpixel.com

I have never experienced loosing DC. Even when changing the resolution.

How do you know you loose it? Post the WindProc too.
So,

I removed my "doOpenGLInit" function and went straight to shutdown, and it works correctly.

I am doing some weirdness for hooking in my WndProc which allows me to intialize my engine from a hwnd parameter.

http://msdn.microsoft.com/en-us/library/ms633591(VS.85).aspx

I think i am doing this incorrectly. (at least not correct enough to release).

I'll post some code when i am home.

------------------------------

redwoodpixel.com

This topic is closed to new replies.

Advertisement