double buffering in Win32 GDI
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
ok, thank you LessBread, i decided to try what you suggested, however i'm still having a probrlem creating the buffer
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]
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
"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
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
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
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement