MFC绘图不闪烁——双缓冲技术[转]
来源:互联网 发布:电脑桌面美化软件排行 编辑:程序博客网 时间:2024/04/30 04:47
在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃。
所谓双缓冲技术,下面是百度百科的解释:
我们看电视时,看到的屏幕称为OSD层,也就是说,只有在OSD层上显示图像我们才能看到。现在,我需要创建一个虚拟的、看不见但是可以在上面画图(比如说画点、线)的OSD层,我称之为offscreen(后台缓冲区)。这个offscreen存在于内存中,我们在上面画图,这个offscreen上面的东西可以显示在OSD层上,需要一个创建这个offscreen的函数,返回这个offscreen的句柄(整型指针)、宽度、高度、指向新建offscreen数据缓冲区的指针,该缓冲区是一个在函数外创建的offscreen的数据缓冲区,大小是offscreen的高度*宽度*每个像素点数据的大小。闪烁是图形编程的一个常见问题。需要多重复杂绘制操作的图形操作会导致呈现的图像闪烁或具有其他不可接受的外观。双缓冲的使用解决这些问题。双缓冲使用内存缓冲区来解决由多重绘制操作造成的闪烁问题。当启用双缓冲时,所有绘制操作首先呈现到内存缓冲区,而不是屏幕上的绘图图面。所有绘制操作完成后,内存缓冲区直接复制到与其关联的绘图图面。因为在屏幕上只执行一个图形操作,所以消除了由复杂绘制操作造成的图像闪烁。
在图形图象处理编程过程中,双缓冲是一种基本的技术。我们知道,如果窗体在响应WM_PAINT消息的时候要进行复杂的图形处理,那么窗体在重绘时由于过频的刷新而引起闪烁现象。解决这一问题的有效方法就是双缓冲技术。
因为窗体在刷新时,总要有一个擦除原来图象的过程On
我们会很自然的想到,避免背景色的填充是最直接的办法。但是那样的话,窗体上会变的一团糟。因为每次绘制图象的时候都没有将原来的图象清除,造成了图象的残留,于是窗体重绘时,画面往往会变的乱七八糟。所以单纯的禁止背景重绘是不够的。我们还要进行重新绘图,但要求速度很快,于是我们想到了使用BitBlt函数。它可以支持图形块的复制,速度很快。我们可以先在内存中作图,然后用此函数将做好的图复制到前台,同时禁止背景刷新,这样就消除了闪烁。以上也就是双缓冲绘图的基本的思路。
先按普通做图的方法进行编程。即在视类的On
CBCDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CPoint ptCenter;
CRect rect,ellipseRect;
GetClientRect(&rect);
ptCenter = rect.CenterPoint();
for(int i=20;i>0;i--)
{
ellipseRect.SetRect(ptCenter,ptCenter);
ellipseRect.InflateRect(i*10,i*10);
pDC->Ellipse(ellipseRect);
}
编译运行程序,尝试改变窗口大小,可以发现闪烁现象。
在双缓冲方法中,首先要做的是屏蔽背景刷新。背景刷新其实是在响应WM_ERASEBKGND消息。我们在视类中添加对这个消息的响应,可以看到缺省的代码如下:
BOOL CMYView::On
{
return CView::On
}
是调用父类的On
下面是内存缓冲作图的步骤。
CPoint ptCenter;
CRect rect,ellipseRect;
GetClientRect(&rect);
ptCenter = rect.CenterPoint();
CDC dcMem; //用于缓冲作图的内存DC
CBitmap bmp; //内存中承载临时图象的位图
dcMem.CreateCompatibleDC(pDC); //依附窗口DC创建兼容内存DC
bmp.CreateCompatibleBitmap(&dcMem,rect.Width(),rect.Height());//创建兼容位图
dcMem.SelectObject(&bmp); //将位图选择进内存DC
dcMem.FillSolidRect(rect,pDC->GetBkColor());//按原来背景填充客户区,不然会是黑色
for(int i=20;i>0;i--) //在内存DC上做同样的同心圆图象
{
ellipseRect.SetRect(ptCenter,ptCenter);
ellipseRect.InflateRect(i*10,i*10);
dcMem.Ellipse(ellipseRect);
}
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY);//将内存DC上的图象拷贝到前台
dcMem.DeleteDC(); //删除DC
bm.DeleteObject(); //删除位图
由于复杂的画图操作转入后台,我们看到的是速度很快的复制操作,自然也就消除了闪烁现象。
- MFC绘图不闪烁——双缓冲技术[转]
- MFC绘图不闪烁——双缓冲技术 [转]
- MFC绘图不闪烁——双缓冲技术[转]
- MFC绘图不闪烁——双缓冲技术
- MFC绘图不闪烁——双缓冲技术
- MFC防止绘图闪烁——双缓冲技术
- 双缓冲技术做到MFC绘图不闪烁!!
- 【转载】MFC绘图不闪烁——双缓冲技…
- c++双缓冲技术绘图避免闪烁
- MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC 双缓冲 绘图时屏幕闪烁问题
- MFC双缓冲绘图解决界面闪烁问题
- MFC中绘图不闪烁
- 双缓冲绘图,防止闪烁
- STL中heap相关函数的用法:make_heap,push_heap,pop_heap...
- 17. Magento 重写控制器
- result_of SFINAE
- angular之$parse
- CentOS6.5安装mysql cluster7.3.7 搭建mysql数据库集群环境(双管理中心)
- MFC绘图不闪烁——双缓冲技术[转]
- CS0234: 命名空间“System.Web.Mvc”中不存在类型或命名空间名称“Ajax”(是否缺少程序集引用?)
- Gradlle 全解析
- 浅谈C#中的双缓冲
- 剖析Disruptor:为什么会这么快?(一)锁的缺点
- arm-linux-androideabi-**工具
- GTK进阶学习:改变控件字体大小
- Ubuntu14.04系统下,如何将.iso文件刻录到CD/DVD光盘
- C# GDI+双缓冲技术