当绘制动态图形时,会遇到图像闪烁的情况,分析一下原因:
电脑屏幕一般都是60HZ的,也就是说一秒钟刷新60次,
但是api绘图却没这么快,本身绘图就要循环,这里面还要加上描点连线,
我们把绘图看成一个个片段,就像电影一样,片段链接在一起就是个动态图像,
这里存在一个问题,
如果说这一个片段能同步屏幕刷新速度,也就是说画好一张图的时候,屏幕还没刷新一次,或者正巧要刷新, 那绘图肯定是完美的,
现在假设绘制一个直线,这个直线有十个点,要花10个图像刷新时间才能完成,那么很显然,这10次刷新过程每个图像都比上一次多一条线段,这就让绘图变成了动态,
而我们的本意是让直线直接画出来,两个端点是同时画的,而这个绘图结果很有可能就闪烁了
解决这个问题其实很简单,我们可以考虑先画好这一条直线,然后一次性投射到屏幕,而不是画一笔显示一次,
这样就用到了双缓冲技术,
这个技术核心就是内存画图,投射屏幕
我们需要创建一个内存兼容DC也叫缓存DC ,但是这个DC不能直接画,因为是单色Pixel,需要绑定一个位图,
位图需要直接创建,默认是全黑的,可以先刷成白的,绑定这个兼容DC进行绘图,后面就跟一般绘图一样,
最后加上一个将兼容DC复制到窗口DC上就行了
HDC hdcmem; //内存DC
HDC hdc; //设备DC
HBITMAP hbm;//位图句柄
scrx = GetSystemMetrics(SM_CXSCREEN); //屏幕宽度
scry = GetSystemMetrics(SM_CYSCREEN); //屏幕高度
hdc = GetDC(hWnd); // 获取设备DC
hdcmem = CreateCompatibleDC(hdc); //创建一个兼容设备的内存DC
// 创建一个位图
hbm = CreateCompatibleBitmap(hdc,scrx,scry);
// 把位图加载到内存DC中,之后的绘图其实就是在位图上绘图
SelectObject( hdcmem , hbm );
//释放DC
ReleaseDC(hWnd,hdc);
// 开始绘图
hdc = BeginPaint(hWnd, &ps);
hbr = (HBRUSH)GetStockObject(WHITE_BRUSH);
//刷白位图
SelectObject(hdcmem,hbr);
Rectangle(hdcmem,0,0,scrx,scry);
DeleteObject(hbr);
/*
* 此处添加绘图代码
*/
//将内存DC 复制到设备DC上
BitBlt(hdc,0,0,scrx,scry,hdcmem,0,0,SRCCOPY);
//结束绘图
EndPaint(hWnd, &ps);