How do I erase the background when doing animations?

Started by
5 comments, last by obi-wan shinobi 18 years, 10 months ago
I'm trying to animate something. In my OnPaint() function, I have a series of gifs that are drawn depending on which was last drawn. I have a timer that calls OnPaint whenever it receives WM_TIMER messages. It works well except for one problem. I don't know how to efficiently erase the background before each new animation frame. I've tried RedrawWindow() but it first erases everything and then draws the new stuff. I've tried doing some weird thing where I just do a return false in the OnEraseBackground() function but this just results in smearing becuase nothing will erase. Any ideas?
Advertisement
Your first solution was the normal way to do it. Just do it like this:

a) Recompute new positions
b) Clear the screen
c) Draw _everything_ (including the stuff that hasn't moved) at it's new position
d) Do it again
How do I clear the screen? With RedrawWindow()?
The problem with RedrawWindow is that everything flashes, even the label and buttons already on my dialog. I don't even draw then in my code. They are done somewhere automatically out of my view (eg..the label that is automatically created that stats "TO DO: Place controls here")
Do u use a doublebuffer?
ok..here it is. I do use double buffer. I noticed that the RDW_INVALIDATE flag seems to be causing major flickering. When I don't include it, the animation just blurs as it keeps drawing on top of itself. When I include the RDW_INVALIDATE flag, it erases but the image remains erased. The new image is unable to be drawn ontop (I can see a faint flicker of the new image but that is it). It is not like how I would imagine normal flickering. I think there is something wrong with the RedrawWindow part.

//I'm only redrawing half of the animation to see what is going on.
RECT visRect = {0,0,32,64};
RedrawWindow(g_hWnd,&visRect,NULL,RDW_ERASE| RDW_INVALIDATE );


//Bitmap memBmp;
HDC hdcMem;
HBITMAP hbmMem;
HANDLE hOld;

// Create an off-screen DC for double-buffering
hdcMem = CreateCompatibleDC(hdcScreen);
hbmMem = CreateCompatibleBitmap(hdcScreen, 64, 64);
hOld = SelectObject(hdcMem, hbmMem);

// Draw into hdcMem...note that i is a changing image
Graphics g2(hdcMem);
g2.DrawImage(&i,0,0,64,64,64,64,UnitPixel );

// Transfer the off-screen DC to the screen
BitBlt(hdcScreen, 0, 0, 64, 64, hdcMem, 0, 0, SRCCOPY);

// Free-up the off-screen DC
SelectObject(hdcMem, hOld);
DeleteObject(hbmMem);
g2.ReleaseHDC(hdcMem);
DeleteDC (hdcMem);
To avoid smearing, I just draw a black rectangle over the whole screen before doing anything else. In my DirectDraw code, I use this kind of structure:

HBRUSH clear = CreateSolidBrush(RGB(0,0,0)); //globals
HDC hdc;

//inside of the painting loop...
RECT screen={0,0,screen_width,screen_height};
//allow back surface to get the device context here
FillRect(hdc,&clear,&screen);
//draw everything here, release the device context, then flip when ready

I don't quite get what you mean by drawing gifs depending on which one was drawn last, so I can't say much about that right now.

This topic is closed to new replies.

Advertisement