使用 DirectDraw 进行双缓冲图形






4.78/5 (12投票s)
2001年9月24日
3分钟阅读

200503

6996
本文介绍如何使用我的CDXSurfaceMgr类来简化双缓冲绘图。
引言
本文介绍如何使用我的 CDXSurfaceMgr
类来简化双缓冲绘图/图形。
双缓冲绘图
通常,在使用GDI绘图时,您将所有绘制直接绘制到HDC
中,该HDC
由BeginPaint
或CDC
(如果您正在使用MFC)提供。如果您绘制一条线,它会立即出现在您正在绘制的窗口的表面上。如果您绘制大量的图形项目,屏幕会随着每个项目进行更新,这可能会导致闪烁或卡顿,因为表面充满了绘图。双缓冲
可用于创建平滑的更新,您首先在不可见的位置构建一个图形“帧”,然后将整个图形复制到主窗口表面。
有很多方法来实现双缓冲,一种方法是在内存中的某个位置创建一个兼容的HDC
,并在其中进行绘制,然后将该内存Blit(复制)到可见的窗口HDC
中。我的方法使用DirectX
的一个子集,称为DirectDraw
,可用于绘制2D图形。CDXSurfaceMgr
是使用VC6(ddraw.h/lib)中提供的DirectDraw接口编写的,应该可以在95/98/Me/2k/XP和NT 4.0(sp3 - 我认为)上运行。
使用CDXSurfaceMgr
创建CDXSurfaceMgr
的一个实例
#include "DXSurfaceMgr.h"
...
...
CDXSurfaceManager_NBP dxMgr_;
像这样初始化该实例int CMfcdxView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // Initialise CDXSurfaceMgr if(!dxMgr_.Initialise(m_hWnd)) return -1; return 0; }这应该只做一次,
Initialise
方法的参数是要绘制的窗口的句柄。然后在处理WM_PAINT
消息(通常进行绘图的地方)时,调用BeginPaint
方法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) { ....
BeginPaint
的参数是一个COLORREF
,BeginPaint
将使用它来填充背景。BeginPaint
返回一个HDC
,您可以使用它来绘制东西,可以通过标准的GDI API;
::SetBkMode(hdc,TRANSPARENT); ::TextOut(hdc,10,10,"Please don't call me reg its not my name", 40);或者如果您使用MFC;
CDC* cdc = CDC::FromHandle(hdc); cdc->SetBkMode(TRANSPARENT); cdc->(10,10, CString("All aboard Brendas iron sledge"));
注意,所有常用的GDI规则都适用 - 如果您选择了一个画笔,记得重新选择旧的画笔等等。当您完成绘图后,像这样调用EndPaint
方法;
dxMgr_.EndPaint();
这会将您的绘图“翻转”到主窗口表面上。并且绘图会立即出现。
CDXSurfaceMgr
的作用
CDXSurfaceMgr
创建一个主表面 - 一个可见的表面 - 和一个辅助的屏幕外表面,该表面与主表面大小相同,但不可见。当您调用BeginPaint
时,将返回一个附加到辅助表面的HDC
;您将所有绘图都绘制到其中;然后EndPaint
将整个辅助表面Blit(复制)到主表面上,它就会出现在窗口上。如果您的机器上有一个强大的图形适配器,那么Blit会非常非常快,如果您没有,那么操作显然不会那么快,但仍然非常有用。
演示
其中包含三个演示,一个使用WFC并绘制在屏幕上上下移动的矩形和椭圆,一个使用MFC,并绘制一些线条和一些文本,另一个再次执行完全相同的操作,但只是一个Win32程序。