From: Sascha on
Hello

I am making my own simple 2d Graphic engine in c++ win32.

The way I draw an object onto the screen is through double buffering:
- I copy the main window HDC into a BufferHDC when the application
loads

Every 100 Clock steps (computer cycles):
Step 1 - I erase an objects previous position from the BufferHDC -
HOW?
Step 2 - I draw an objects new position onto the bufferHDC -
FillRegion(BufferHDC, ...);
Step 3 - I then copy the bufferHDC to the main HDC


My problem:
I dont know how to do Step 1? How do I delete/erase an area of a HDC/
Bitmap? I know how to erase a HRGN from the main window using
InvalidateRgn() but how do I erase a HRGN from my BufferRgn.

I know I can just use InvalidateRgn() thus erase the region from the
main window then draw onto the BufferHDC etc. But the delay between
erasing, drawing then erasing is long enough to create a flicker
effect which completely defeats the purpose of using double buffering
in the 1st place.

I also know I could clear the BufferHDC (of ALL objects) every clock
rotation, then just draw every object again(regardless of if they need
to be redrawn or not) but this is inefficient.

Any suggestions would be extremely helpful :)

My current Draw function which doesn't erase a region from the HDC yet
[source]
bool DrawEngine :: ExecuteDraw( HDC WindowHDC )
{
// Post: Draw all 'Dirty' Objects onto window using Double
Buffering (avoids
// flicker affect).

// PROBLEM: Because I erase an objects old position from the main
window(instead of buffer HDC)
// & then redraw its new postion in this function there is
a short delay between
// erasing then redrawing (causing flickering) which
defaults the whole purpose of
// double buffering.
//
// Is there a way to erase the object's old position from
the buffer HDC bitmap?
// Is there a better way to do this that I am not
considering?



// Copy window to buffer canvas
// In reality this maybe only needs to be done once(copying Window
HDC to buffer HDC) but when
// & where should I do this; In WM_CREATE, in WM_PAINT (it will be
done every time the msg is called
// wont it?) or other?


RECT ClientRect;
GetClientRect( hwnd, &ClientRect );
BufferCanvas = CreateCompatibleDC( WindowHDC );
HBITMAP hBlt = CreateCompatibleBitmap( WindowHDC,
ClientRect.right,
ClientRect.bottom );
HGDIOBJ hMCBmp = SelectObject( BufferCanvas, hBlt );

BitBlt(BufferCanvas, ClientRect.left, ClientRect.top,
ClientRect.right,
ClientRect.bottom, WindowHDC, 0, 0, SRCCOPY );



// Draw objects onto Buffer Canvas
while ( !qDrawList.empty() )
{
qDrawList.front()-> DrawSelf( BufferCanvas );
qDrawList.pop();
}



// Copy BufferCanvas HDC to WindowCanvas HDC
BitBlt( WindowHDC, ClientRect.left, ClientRect.top,
ClientRect.right,
ClientRect.bottom, BufferCanvas, 0, 0, SRCCOPY );

SelectObject( BufferCanvas, hMCBmp );
DeleteObject( hBlt );
DeleteDC( BufferCanvas );
}
[/source]
From: Dee Earley on
On 01/06/2010 11:07, Sascha wrote:
> Hello
>
> I am making my own simple 2d Graphic engine in c++ win32.
>
> The way I draw an object onto the screen is through double buffering:
> - I copy the main window HDC into a BufferHDC when the application
> loads
>
> Every 100 Clock steps (computer cycles):
> Step 1 - I erase an objects previous position from the BufferHDC -
> HOW?
> Step 2 - I draw an objects new position onto the bufferHDC -
> FillRegion(BufferHDC, ...);
> Step 3 - I then copy the bufferHDC to the main HDC
>
>
> My problem:
> I dont know how to do Step 1? How do I delete/erase an area of a HDC/
> Bitmap? I know how to erase a HRGN from the main window using
> InvalidateRgn() but how do I erase a HRGN from my BufferRgn.

You just draw the "background" on top of it, however, you may find it
easier just to redraw all of it.

--
Dee Earley (dee.earley(a)icode.co.uk)
i-Catcher Development Team

iCode Systems

(Replies direct to my email address will be ignored.
Please reply to the group.)
From: Piranha on
On 1 Jun., 12:07, Sascha <nill...(a)yahoo.com> wrote:
> Hello
>
> I am making my own simple 2d Graphic engine in c++ win32.
>
> The way I draw an object onto the screen is through double buffering:
> - I copy the main window HDC into a BufferHDC when the application
> loads
>
>   Every 100 Clock steps (computer cycles):
>     Step 1 - I erase an objects previous position from the BufferHDC -
> HOW?
>     Step 2 - I draw an objects new position onto the bufferHDC -
> FillRegion(BufferHDC, ...);
>     Step 3 - I then copy the bufferHDC to the main HDC
>
> My problem:
> I dont know how to do Step 1? How do I delete/erase an area of a HDC/
> Bitmap? I know how to erase a HRGN from the main window using
> InvalidateRgn() but how do I erase a HRGN from my BufferRgn.
>
> I know I can just use InvalidateRgn() thus erase the region from the
> main window then draw onto the BufferHDC etc. But the delay between
> erasing, drawing then erasing is long enough to create a flicker
> effect which completely defeats the purpose of using double buffering
> in the 1st place.
>
> I also know I could clear the BufferHDC (of ALL objects) every clock
> rotation, then just draw every object again(regardless of if they need
> to be redrawn or not) but this is inefficient.
>
> Any suggestions would be extremely helpful :)
>
> My current Draw function which doesn't erase a region from the HDC yet
> [source]
> bool DrawEngine :: ExecuteDraw( HDC WindowHDC )
> {
>    // Post: Draw all 'Dirty' Objects onto window using Double
> Buffering (avoids
>    //       flicker affect).
>
>    // PROBLEM: Because I erase an objects old position from the main
> window(instead of buffer HDC)
>    //          & then redraw its new postion in this function there is
> a short delay between
>    //          erasing then redrawing (causing flickering) which
> defaults the whole purpose of
>    //          double buffering.
>    //
>    //          Is there a way to erase the object's old position from
> the buffer HDC bitmap?
>    //          Is there a better way to do this that I am not
> considering?
>
>    // Copy window to buffer canvas
>    // In reality this maybe only needs to be done once(copying Window
> HDC to buffer HDC) but when
>    // & where should I do this; In WM_CREATE, in WM_PAINT (it will be
> done every time the msg is called
>    // wont it?) or other?
>
>    RECT ClientRect;
>    GetClientRect( hwnd, &ClientRect );
>    BufferCanvas = CreateCompatibleDC( WindowHDC );
>    HBITMAP hBlt   = CreateCompatibleBitmap( WindowHDC,
> ClientRect.right,
>                                             ClientRect.bottom );
>    HGDIOBJ hMCBmp = SelectObject( BufferCanvas, hBlt );
>
>    BitBlt(BufferCanvas, ClientRect.left, ClientRect.top,
> ClientRect.right,
>           ClientRect.bottom, WindowHDC, 0, 0, SRCCOPY );
>
>    // Draw objects onto Buffer Canvas
>    while ( !qDrawList.empty() )
>    {
>         qDrawList.front()-> DrawSelf( BufferCanvas );
>         qDrawList.pop();
>    }
>
>    // Copy BufferCanvas HDC to WindowCanvas HDC
>    BitBlt( WindowHDC, ClientRect.left, ClientRect.top,
> ClientRect.right,
>            ClientRect.bottom, BufferCanvas, 0, 0, SRCCOPY );
>
>    SelectObject( BufferCanvas, hMCBmp );
>    DeleteObject( hBlt );
>    DeleteDC( BufferCanvas );}
>
> [/source]

Keep another static HDC / HBITMAP containing the original content of
the window, then instead of step 1, copy that into the buffer.