Advertisement

double buffering in Win32 GDI

Started by April 17, 2002 09:28 AM
6 comments, last by alexdevmaster 22 years, 10 months ago
i''m having a real hard time gettin my double buffer to work, when i was doing it in DirectX it was easy, well i had my book to help me that is "Tricks of the Windows Game Programming Gurus" but now that i''m trying to do it in Win GDI it isnt workign that well, right now what i''ve done is to create a temporty Bitmap and Device Context, I then do all my drawing on this Bitmap and the BitBlt it to the main Dc, like so void Play_Game(){ GetClientRect(g_hwnd,&rcClient); hdcBuffer = CreateCompatibleDC(g_mainDC); hbmBuffer = CreateCompatibleBitmap(g_mainDC, rcClient.right, rcClient.bottom); hbmOldBuffer = (HBITMAP)SelectObject(hdcBuffer, hbmBuffer); //do my drawing and stuff //copy to main DC BitBlt(g_mainDC, 0, 0, rcClient.right, rcClient.bottom, hdcBuffer, 0, 0, SRCCOPY); //release buffer and stuff }//end play_game I call this play_game function in WM_PAINT like this case WM_PAINT:{ PAINTSTRUCT ps; g_mainDC = BeginPaint(g_hwnd,&ps); Play_Game(); EndPaint(g_hwnd,&ps); return(0); } and then in my main while loop i have this while(TRUE) { int iStartTime = GetTickCount(); //event loop is here InvalidateRect(g_hwnd,&rcClient,TRUE); //lock frame rate to 33 fps while((GetTickCount() - iStartTime)<30); }//end main loop So what i''m doing is i''m invalidating the client window in the while and relying on WM_PAINT to do the processing. Could i be doin this better, right now my game flickers badly. So i know something isnt goin right with the double buffering "Jus chillin waiting for my time to shine" #define ALEX_DENNIS
"Jus chillin waiting for my time to shine"#define ALEX_DENNIS
Um... lets see - this won''t solve everything but at least it will give your question a bump. Create the memory DC on init and store it in a global variable. Set the background brush to NULL to avoid repainting the back ground. Move the call to Play_Game from WM_PAINT and into the message loop - but only after reconfiguring the message loop. There are a few other things to note as well, but start with these, they should get you on your way.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Advertisement
ok, thank you LessBread, i decided to try what you suggested, however i'm still having a probrlem creating the buffer

this is is how i created it at initialization




  [b]void Load_Graphics() {    GetClientRect(NULL,&rcClient);    g_mainDC=GetDC(g_hwnd);    hdcBuffer = CreateCompatibleDC(g_mainDC);    hbmBuffer = CreateCompatibleBitmap(g_mainDC, rcClient.right, rcClient.bottom);    hbmOldBuffer = (HBITMAP)SelectObject(hdcBuffer, hbmBuffer);    ReleaseDC(NULL,g_mainDC);} //end load graphics[/b]  


and this is how i delete it at the end



  void BlowUp_Graphics() {	SelectObject(hdcBuffer, hbmOldBuffer);	DeleteDC(hdcBuffer);	DeleteObject(hbmBuffer);}//end BlowUp_Graphics  


i havent made any other alterations to my code, but now nothing comes up on the screen, am i doing something wrong


"Jus chillin waiting for my time to shine"
#define ALEX_DENNIS


[edited by - alexdevmaster on April 17, 2002 5:38:07 PM]
"Jus chillin waiting for my time to shine"#define ALEX_DENNIS
Ok. I went and looked at some older code I had for initializing an offscreen buffer. It''s not how I would go about it today, but it works. Hopefully you can adapt it to work with your code.


  HDC  __stdcall InitializeOffScreenBuffer(HWND hwnd){	HDC memdc = NULL;	HDC hdc = GetDC(hwnd);	// a global variable might be preferable	// moreso considering this property won''t change	BOOL g_BltCap = ( GetDeviceCaps(hdc, RASTERCAPS) & RC_BITBLT );	if ( g_BltCap )	{		RECT rect;		HBITMAP hBitMap, hTempBitMap;		HBRUSH hBrush, hTempBrush;		memdc = CreateCompatibleDC(hdc);		GetWindowRect(hwnd,▭);		hBitMap = CreateCompatibleBitmap(hdc, rect.right, rect.bottom);		hTempBitMap = SelectObject(memdc, hBitMap);		hBrush = GetStockObject(BLACK_BRUSH);		hTempBrush = SelectObject(memdc, hBrush);		PatBlt( memdc				, rect.left				, rect.top				, rect.right				, rect.bottom				, PATCOPY);		// select object returns handle of object being replaced		DeleteObject( SelectObject(memdc, hTempBrush) );		// deleting the selected bitmap prevents memdc from working properly		// DeleteObject( SelectObject(memdc, hTempBitMap) );	}	ReleaseDC(hwnd, hdc);	return( memdc );}// call this to clean up the mem dc// from WM_CLOSE for exampleDeleteDC(g_MemDC);// Blit g_MemDC to g_hDCVOID __stdcall UpdateScreen(HWND hwnd, HDC memdc){	HDC hdc = GetDC(hwnd);	// a global variable might be preferable	// moreso considering this property won''t change	if ( GetDeviceCaps(hdc, RASTERCAPS) & RC_BITBLT )	{		// a global variable might be preferable		RECT rect;		GetWindowRect(hwnd, ▭);		BitBlt(hdc			, rect.left, rect.top			, rect.right, rect.bottom			, memdc			, rect.left, rect.top			, SRCCOPY);	}	// not absolutely required for OWNDC	// determine if it hurts and leave it if it doesn''t	ReleaseDC(hwnd, hdc);}// main game loopBOOL Game_Main(void){// do stuff like check keyboard etc// clear out the offscreen buffer	PatBlt(g_MemDC, 0, 0, WorkArea.right, WorkArea.bottom, BLACKNESS);// draw on the offscreen buffer// setpixel, textout, etc...	// blit memdc to hdc	UpdateScreen(g_hWnd,g_MemDC);	return(TRUE);}// and here is a message loop that can be used to run the game// again, it''s not how I would do it today, but it works// enter main event loop	while(TRUE)	{		// test for message in queue, if so get it		if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )		{			if (msg.message == WM_QUIT)			{				break;			}			// translate accelerator keys			TranslateMessage(&msg);			// send the message to the window proc			DispatchMessage(&msg);		}		// main game processing		Game_Main();	}// cleanup/return  
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
ok thanks again, i''m going to see if this can help me, I pray to God it does, cus this is stressing, fun :-) but stressing

"Jus chillin waiting for my time to shine"
#define ALEX_DENNIS
"Jus chillin waiting for my time to shine"#define ALEX_DENNIS
this double buffering stuff sucks

or should i say win GDI sucks when it comes to double buffering

as it stands right now, i''m at a loss, i''m sure i''m doing it right but mothing comes on the screen when i attempt a double buffer system. also i realise that when i try to do my drawing on a global dc as opposed to making one every time i want to draw it doesnt work. I cant understand this, should i be able to GetDC once do drawing and then ReleaseDC. that doesnt work for me, i have to create a local buffer in my drawing function, thats the only way it works, not to mention my double buffer, that doesnt work whether its global or local, i''ve tried everything already suggested in the discussion. HELP!!!

"Jus chillin waiting for my time to shine"
#define ALEX_DENNIS
"Jus chillin waiting for my time to shine"#define ALEX_DENNIS
Advertisement
Alex, email me all your source code, I''ll see what I can do with it over the weekend.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
prionx@juno.com, i hope that was the right email address, i just send all my source there, I really hope you can help me out, thank you :-)

"Jus chillin waiting for my time to shine"
#define ALEX_DENNIS
"Jus chillin waiting for my time to shine"#define ALEX_DENNIS

This topic is closed to new replies.

Advertisement