Sign in to follow this  

C++ Win32 Double Buffering problems

This topic is 2584 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello. I've been trying to implement double buffering into my app. The reason for this is to reduce the amount of flickering, due to high refresh rate. However, with double buffering it flickers even worse, the background is black and the old bitmap is not erased before drawing a new one. I'm obviously not doing it right, but I couldn't find a comprehensive description online that would point out what params are responsible for what.
Here is the code:

//All variables starting with g are globals.
//this is the part of the WndProc function that is relevant to painting
ghwnd=hWnd;
BP_PAINTPARAMS paintParams = {BPPF_ERASE};
paintParams.cbSize = sizeof(paintParams);
switch(message)
{
case WM_PAINT:
//update the game
gGame.tick();
//refresh the graphics sprite list
gGraphics.prepareFrame();
//update the mouse highlights
gSelection.onMove();
//draw the graphics
ghdc = BeginPaint(hWnd, &gps);

ghpbuff=BeginBufferedPaint(ghdc, &gwndrect, BPBF_COMPATIBLEBITMAP, &paintParams, &ghdcbuff);
if (ghpbuff)
{
// Application specific painting code
gGraphics.drawFrame();
EndBufferedPaint(ghpbuff, TRUE);
}
else
{
// Error occurred, default to unbuffered painting
ghdcbuff=ghdc;
gGraphics.drawFrame();
}
EndPaint(hWnd, &gps);

//
break;

//the function that draws the frame
void BBGraphics::drawFrame()
{
for(unsigned int i=0;i<sprites.size();i++)
if(sprites[i])
sprites[i]->draw();
redraw=false;
}
//those are the two possible sprite.draw functions, as sprite and text are both reated as sprites
void BBSprite::draw()
{
//grab a brush
HBRUSH brush=gGraphics.getBrush(color);
//draw teh rectangle
FillRect(ghdcbuff, &rect, brush);
}
void BBText::draw()
{
SetTextColor(ghdc, color);
TextOut(ghdcbuff, rect.left, rect.top, text, text.length());
}




I am not sure if that's all that is relevant, but the program is pretty big. The code for double buffering was taken from MSDN BufferedPaint functions descriptions. As I said, with this code, problems from unbuffered painting are carried over tenfold. So how do I use that thing?

Share this post


Link to post
Share on other sites
The first thing I would check would be to see what your WNDCLASS structure is set like. You'll want to look at the hbrBackground member and see if it's assigned to NULL or not. The reason being is that to help speed up painting, you'll want to handle the WM_ERASEBACKGROUND message (which setting it to NULL will do), or manually handle it yourself. Otherwise, it doesn't matter if you double buffer or not, Windows will automatically try redrawing the background, giving a flickering appearance each time.

Also, if using BeginBufferedPaint, you'll want to make sure you call BufferedPaintInit and BufferedPaintUnInit at the beginning and end of the thread (or process in your case), else it will keep initializing and unitializing data every time you call that function.

Share this post


Link to post
Share on other sites
Well, that's my window initialization class:

WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = CreateSolidBrush(RGB(255,255,255));
wcex.lpszMenuName = NULL;
wcex.lpszClassName = _T("BBMainWnd");
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));



I set the hbrBackground to a white brush, hoping that it would actually make the background white, instead of black. Also, I do call BufferedPaintInit and BufferedPaintUnInit on WM_CREATE and WM_NCDESTROY messages respectively. I'm not sure how I am supposed to be handling background redrawing though.

Share this post


Link to post
Share on other sites

This topic is 2584 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this