Click here to Skip to main content
11,484,752 members (67,343 online)
Click here to Skip to main content

Double Buffered Graphics using DirectDraw

, 23 Sep 2001 163.3K 6.1K 71
Rate this:
Please Sign up or sign in to vote.
This article explains how my class CDXSurfaceMgr can be used to facilitate Double Buffered drawing.
<!-- Download Links --> <!-- Article image -->

Sample Image - DXSurfaceMgr.gif

<!-- Main HTML starts here -->

Introduction

This article explains how my class CDXSurfaceMgr can be used to facilitate Double Buffered drawing/graphics.

Double Buffered Drawing

Normally when drawing using the GDI you do all your painting straight into the HDC that's provided by either BeginPaint or a CDC (if you are using MFC). Iif you draw a line it immediately appears on the surface of the window you are drawing on. If you draw a lot of graphic items the screen is updated with each item and this can result in flicker or stuttering as the surface is filled with the drawing. Double Buffering can be used to create smooth updates, you build a "frame" of graphics in a non visible place first then copy the whole thing onto the main windows surface.

There a lots of ways to implement double buffering, one way is to create a compatible HDC in memory somewhere and draw into that then Blit (copy) that memory into the visible windows HDC. My approach uses a subset of DirectX called DirectDraw which can be used to draw 2d Graphics. CDXSurfaceMgr is written using the DirectDraw interfaces supplied in VC6 (ddraw.h/lib) and should work on 95/98/Me/2k/XP and NT 4.0 (sp3 - I think).

Using CDXSurfaceMgr

Create an instance of CDXSurfaceMgr

#include "DXSurfaceMgr.h"
...
...
CDXSurfaceManager_NBP dxMgr_;
Initialise the instance like so
int CMfcdxView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CView::OnCreate(lpCreateStruct) == -1)
         return -1;
 // Initialise CDXSurfaceMgr
 if(!dxMgr_.Initialise(m_hWnd)) return -1;

 return 0;
}
This should be done just once, the parameter to the Initialise method is the Handle to the window you want to draw on. Then when handling the WM_PAINT message (the place you would normally do the drawing) call the BeginPaint Method
void CMfcdxView::OnDraw(CDC* pDC)
{
 CMfcdxDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 // TODO: add draw code for native data here

 HDC& hdc = dxMgr_.BeginPaint(GetSysColor(COLOR_3DFACE));
 if(NULL !=hdc)
 {
 ....

The parameter to BeginPaint is a COLORREF that BeginPaint will use to fill the background with. BeginPaint returns an HDC that that you can then use to draw things with, either via the standard GDI API;

 ::SetBkMode(hdc,TRANSPARENT);
 ::TextOut(hdc,10,10,"Please don't call me reg its not my name", 40);
Or if you are using MFC;
 CDC* cdc = CDC::FromHandle(hdc);
 cdc->SetBkMode(TRANSPARENT);
 cdc->(10,10, CString("All aboard Brendas iron sledge"));

Note all the usual GDI rules apply - if you select a brush remember to reselect the old one etc. When you have finished drawing, call the EndPaint method like so;

dxMgr_.EndPaint();

This will "flip" your drawing onto the main windows surface. and the drawing will instantaneously appear.

What CDXSurfaceMgr does

CDXSurfaceMgr creates a primary surface - one that is visible - and a secondary off screen surface that is the same size as the primary one but invisible. When you call BeginPaint an HDC attached to the secondary surface is returned; you do all your drawing into this; then EndPaint Blits(copies) the whole of the secondary surface onto the primary one and it appears on the window. If you have a capable graphics adapter on your machine then the Blit is very very fast, if you don't then the operation is obviously not as fast, but still very functional.

Demos

There are three demos included one that uses WFC and draws rectangles and ellipses moving up and down the screen, one that uses MFC, and draws a few lines and a bit of text, and one that does exactly the same again but is just a Win32 program.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Gertruud Lawrence

United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
QuestionCDialog problem Pin
PeterHo38618-Oct-11 17:23
memberPeterHo38618-Oct-11 17:23 
Hi,

When I implement the DirectDraw in CDialog::OnPaint(), the onpaint() is called endlessly. And then, the CPU loading is 50% high.

How to fix it in CDialog ?


Thanks!
GeneralAlpha support Pin
nesculcas10-Feb-07 7:16
membernesculcas10-Feb-07 7:16 
GeneralWorking sample Pin
nesculcas8-Feb-07 14:40
membernesculcas8-Feb-07 14:40 
GeneralRe: Working sample Pin
nesculcas10-Feb-07 5:49
membernesculcas10-Feb-07 5:49 
GeneralRe: Working sample Pin
nesculcas10-Feb-07 7:17
membernesculcas10-Feb-07 7:17 
GeneralUuups, did you ever try... Pin
a coder7-Apr-05 21:23
membera coder7-Apr-05 21:23 
GeneralRe: Uuups, did you ever try... Pin
x-plorer7-Apr-05 22:39
memberx-plorer7-Apr-05 22:39 
Generalhuge memory leaks ! Pin
cnkKlau10-Mar-05 1:26
membercnkKlau10-Mar-05 1:26 
Generalpull-down menue updates Pin
Sagi dror10-May-04 1:33
sussSagi dror10-May-04 1:33 
GeneralUse in Dialog bases app Pin
Ruination28-Aug-03 13:54
memberRuination28-Aug-03 13:54 
GeneralCDXSurfaceMgr stops working after screen saver has been activated Pin
Johanps17-Jun-03 4:22
memberJohanps17-Jun-03 4:22 
GeneralRe: CDXSurfaceMgr stops working after screen saver has been activated Pin
shorer30-Aug-09 1:46
membershorer30-Aug-09 1:46 
QuestionWhy here not Visual Basic? Pin
niekass12-Jun-03 3:06
sussniekass12-Jun-03 3:06 
QuestionWhy here not Visual Basic? Pin
niekasss12-Jun-03 2:40
memberniekasss12-Jun-03 2:40 
AnswerRe: Why here not Visual Basic? Pin
Twink9-Jan-05 14:57
memberTwink9-Jan-05 14:57 
GeneralSetDIBitsToDevice Pin
Anonymous1-Apr-02 23:19
memberAnonymous1-Apr-02 23:19 
GeneralThanks so much Pin
ackka7-Jan-02 11:11
memberackka7-Jan-02 11:11 
GeneralTheres a leak in my code Pin
gerty29-Sep-01 13:08
membergerty29-Sep-01 13:08 
GeneralGreat code... and a question Pin
Matt Ashland25-Sep-01 16:38
memberMatt Ashland25-Sep-01 16:38 
GeneralRe: Great code... and a question Pin
gerty29-Sep-01 12:41
membergerty29-Sep-01 12:41 
GeneralRe: Thanks... and a benchmark Pin
Matt Ashland1-Oct-01 4:26
memberMatt Ashland1-Oct-01 4:26 
Generalatlres.h missing Pin
Friedhelm Schuetz25-Sep-01 5:33
memberFriedhelm Schuetz25-Sep-01 5:33 
GeneralRe: atlres.h missing Pin
Matt Ashland25-Sep-01 18:09
memberMatt Ashland25-Sep-01 18:09 
GeneralRe: atlres.h missing Pin
gerty29-Sep-01 12:44
membergerty29-Sep-01 12:44 
GeneralInteresting... Pin
J.G. Hattingh25-Sep-01 3:47
memberJ.G. Hattingh25-Sep-01 3:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150520.1 | Last Updated 24 Sep 2001
Article Copyright 2001 by Gertruud Lawrence
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid