GDI双缓冲绘图
一、简介
在进行复杂图形绘制时,若直接在屏幕DC上进行绘制,则会出现明显的闪烁。闪烁产生的原因是当绘制的图形较为 复杂时,图形绘制过程中就被刷新到屏幕上,导致结果断断续续地显示出来。双缓冲绘图的原理是在另开辟一块内存用于绘制,当所有绘制工作完成后将内存数据一 次性拷贝到屏幕上。
双缓冲绘图步骤:
创建兼容DC(CreateCompatibleDC)
创建兼容位图(CreateCompatibleBitmap)
将兼容位图选入兼容DC(SelectObject)
在兼容DC中进行绘制工作
将兼容DC中的像素拷贝至屏幕DC(BitBlt)
从兼容DC中换出兼容位图(SelectObject)
删除兼容位图(DeleteObject)
删除兼容DC(DeleteObject)
二、实现:
演示程序绘制了从窗口中心发射的300条射线,为了凸显双缓冲的效果,特意在绘制每条线段时添加延时操作(sleep)。可以发现,若直接在屏幕DC上绘制,能够明显感觉到每条线段的绘制过程,而采用双缓冲则无此现象。
直接绘制代码:
void CtestBFDlg::OnBnClickedDirectDraw()
{
// TODO: 在此添加控件通知处理程序代码
CPen newPen;
CPen *pOldPen;
CBrush newBrush;
CBrush *pOldBrush;
CRect zcRect;
CDC *pDc;
CPoint cenpoint;
CPoint point; pDc = Picture.GetDC();
Picture.GetClientRect(&zcRect);
newPen.CreatePen(PS_SOLID,,RGB(,,));//画笔
pOldPen = pDc->SelectObject(&newPen);
newBrush.CreateSolidBrush(RGB(,,));//画刷
pOldBrush=pDc->SelectObject(&newBrush); //绘制工作(直接在屏幕DC上作图)
pDc->FillRect(zcRect,&newBrush);
float radius=;
float degree=;
float x,y;
float cenx,ceny;
cenx=zcRect.Width()/2.0;
ceny=zcRect.Height()/2.0;
cenpoint.x=cenx;
cenpoint.y=ceny;
for(int i=;i<;i++)
{
pDc->MoveTo(cenpoint);
degree=*PI/*i;
point.x=radius*cos(degree)+cenx;
point.y=radius*sin(degree)+ceny;
Sleep(); //刻意延时以凸显效果
pDc->LineTo(point);
}
pDc->SelectObject(pOldPen);
pDc->SelectObject(pOldBrush);
newBrush.DeleteObject();
newPen.DeleteObject();
ReleaseDC(pDc);
}
双缓冲绘制代码:
void CtestBFDlg::OnBnClickedDFDraw()
{
// TODO: 在此添加控件通知处理程序代码
CPen newPen;
CPen *pOldPen;
CBrush newBrush;
CBrush *pOldBrush;
CRect zcRect;
CDC *pDc;
CPoint cenpoint;
CPoint point;
pDc = Picture.GetDC();
Picture.GetClientRect(&zcRect); CDC dc;
dc.CreateCompatibleDC(pDc);//创建兼容DC
CBitmap memBmp;
memBmp.CreateCompatibleBitmap(pDc, zcRect.Width(), zcRect.Height());//创建兼容位图
CBitmap* OldBmp = dc.SelectObject(&memBmp);//将位图选入DC newPen.CreatePen(PS_SOLID,,RGB(,,));
pOldPen = dc.SelectObject(&newPen);
newBrush.CreateSolidBrush(RGB(,,));
pOldBrush=dc.SelectObject(&newBrush); //绘制工作(在兼容DC中作图)
//****************************************************************
dc.FillRect(zcRect,&newBrush);
float radius=;
float degree=;
float x,y;
float cenx,ceny;
cenx=zcRect.Width()/2.0;
ceny=zcRect.Height()/2.0;
cenpoint.x=cenx;
cenpoint.y=ceny;
for(int i=;i<;i++)
{
dc.MoveTo(cenpoint);
degree=*PI/*i;
point.x=radius*cos(degree)+cenx;
point.y=radius*sin(degree)+ceny;
Sleep(); //此处刻意延时以凸显效果
dc.LineTo(point);
}
//****************************************************************
pDc->BitBlt(,,zcRect.Width(),zcRect.Height(),&dc,,,SRCCOPY);//将兼容DC中位图拷贝至屏幕DC
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);
dc.SelectObject(OldBmp);
newBrush.DeleteObject();
newPen.DeleteObject();
memBmp.DeleteObject();
dc.DeleteDC();
ReleaseDC(pDc);
}
界面:
GDI双缓冲绘图的更多相关文章
- C#-gdi绘图,双缓冲绘图,Paint事件的触发
一. 画面闪烁问题与双缓冲技术 1.1 导致画面闪烁的关键原因分析: 1 绘制窗口由于大小位置状态改变进行重绘操作时 绘图窗口内容或大小每改变一次,都要调用Paint事件进行重绘操作,该操作会使画面 ...
- 陈灯WGF双缓冲绘图框架
“木丸子童屋”,专售各类儿童玩具,价格优惠,请大家多多支持:http://shop65552598.taobao.com/ WGF(windows graphic foundation)为window ...
- mfc双缓冲绘图
1.要求 在界面加载本地图片并显示,每过100ms改变一张图片显示 2.现象 通过定时器控制CImage,Load,Draw,Destroy,会非常的卡顿.因为Load图片时,会是非常大的数据[所有C ...
- C# GDI+双缓冲技术
我想有很多搞图形方面的朋友都会用到双缓冲技术的时候,而且有的时候她的确是个头疼的问题.最近我也要用双缓冲技术,程序怎么调试都不合适,当要对图形进行移动时,总是会出现闪烁抖动.在网上找了些资料,说得都不 ...
- MFC双缓冲绘图(2015.09.24)
问题引入: 最近在尝试编写贪吃蛇游戏时遇到这么一个问题:当系统以较快频率向窗口发送WM_PAINT消息时,调用OnPaint()函数在窗口中绘制图形就会发生闪烁现象. 问题分析: 当我们把绘图过程放在 ...
- MFC双缓冲绘图实例
本人之前一直了解双缓冲绘图的基本原理,但是在研究很久之后才大概知道具体的使用过程,本文将详细介绍本人在实际项目中使用双缓冲绘图的案例. 实现功能:主界面显示某张包含人脸的图片,通过dlib detec ...
- 双缓冲绘图和窗口控件的绘制——ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 .
双缓冲绘图和窗口控件的绘制 ---ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 cheungmine 我们通常使用ATL COM组件,生成一个带窗口的ActiveX控件,然后 ...
- 简单的 "双缓冲" 绘图的例子(研究一下)
所谓双缓冲就是先画到内存画布(如: TBitmap), 然后再转帖到目的地. 譬如下面小程序: procedure TForm1.FormCreate(Sender: TObject); begin ...
- 【MFC】MFC绘制动态曲线,用双缓冲绘图技术防闪烁
摘自:http://zhy1987819.blog.163.com/blog/static/841427882011614103454335/ MFC绘制动态曲线,用双缓冲绘图技术防闪烁 2011 ...
随机推荐
- Spring Batch(4): Job具体解释
第四章 配置作业Job 4.1 基本配置 Job的配置有3个必须的属性.name,jobRepository,steps.一个简单的Job配置例如以下: <job id="footba ...
- V-Play 文档翻译 Page
V-Play 文档翻译 Page 翻译:qyvlik 应用的一个页面. VPlayApps 1.0 Inherits: MouseArea Inherited By: ListPage 属性 Item ...
- set -- $variable
1 set --的用途 给位置参数赋值. 2 $variable是如何赋值给位置参数的 假如variable=a b c?或者variable=a;b;c? 这里果然和IFS有关,默认情况下,vari ...
- socketIO原理图
- caioj1462: 【EXKMP】回文串
不得不说这是一道好题(前排膜拜灯教授),其实这道题如果不说是EXKMP,很容易就想到Manacher(好像也可以这样做) 回到这道题,这样只有一个字符串,还要求回文?立刻想到了将这个串和它的反串跑EX ...
- C++的学习 (此博客将一直补充更新下去,C++语法方面的内容不开新随笔了, *【语法学习】)
// #include <sstream> // stringstream 是 C++ 提供的另一个字串型的串流(stream)物件,包含在上述头文件中 // 先谈它在字符串处理方面的应用 ...
- Jackson序列化和反序列化
1,下载Jackson工具包(jackson-core-2.2.3.jar jackson-annotations-2.2.3.jar jackson-databind-2.2.3.jar ) j ...
- html5--6-59 其他常用CSS属性
html5--6-59 其他常用CSS属性 实例 学习要点 了解opacity属性:透明度设定 了解cursor属性:自定义鼠标样式 了解CSS新单位rem和em的区别 了解轮廓outline的设置 ...
- UVA - 10004 Bicoloring(判断二分图——交叉染色法 / 带权并查集)
d.给定一个图,判断是不是二分图. s.可以交叉染色,就是二分图:否则,不是. 另外,此题中的图是强连通图,即任意两点可达,从而dfs方法从一个点出发就能遍历整个图了. 如果不能保证从一个点出发可以遍 ...
- 树莓派Dietpi系统配置Dueros
dietpi 系统安装alsa工具 安装依赖 sudo apt-get install python-dateutil sudo apt-get install gir1.2-gstreamer- ...