如何实现双缓冲

如何实现双缓冲  

双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。双缓冲实现过程如下:

1、在内存中创建与画布一致的缓冲区

2、在缓冲区画图

3、将缓冲区位图拷贝到当前画布上

4、释放内存缓冲区

  
   
(1)在内存中创建与画布一致的缓冲区

CDC dc;//这是窗口的DC,假设已加载好  

CDC MemDC;   //创建内存中的一个临时dc-MemDC,MemDC用来向窗口绘图的“草稿”
    
  //随后建立与屏幕显示兼容的内存显示设备  
  MemDC.CreateCompatibleDC(&dc); //这时还不能绘图,因为没有地方画   ^_^  
  //创建的临时空白bitmap作为“画布”,至于位图的大小,可以用窗口的大小 

CBitmap MemBitmap; 
  MemBitmap.CreateCompatibleBitmap(&dc,nWidth,nHeight); 
  
  //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上  
  CBitmap  *pOldBit=MemDC.SelectObject(&MemBitmap); //将上面创建的临时“画布”MemBitmap与MemDC连接,注意此处的MemBitmap为一个空白临时画布, 可以在这个空白画布上自绘图,也可以在这个画布上加载图片
   
  //先用背景色将位图清除干净,这里我用的是白色作为背景  
  //你也可以用自己应该用的颜色  
  MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255)); 
   
(2)在缓冲区画图

 
  MemDC.MoveTo(……);  
  MemDC.LineTo(……);  
(2)'在第(2)步中,如果不是自绘图,而是加载一个位图,则需要再定义一个临时dc-MemDC2,用来将位图加载到上面建立的空白画布MemDC中

CBitmap p1;//这是要画的位图,假设已加载好

 

CDC MemDC2;

MemDC2.CreateCompatibleDC(&dc);

MemDC2.SelectObject(&p1);// MemDC2与图片链接

//在这里,p1保存的是要加载到临时空白画布上的图片,MemDC2是与p1链接的dc

 

(3)将缓冲区位图拷贝到当前画布(屏幕)上
 dc.BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);

(3)’如果是位图的话

首先,将与MemDC2链接的位图p1拷贝到临时空白画布MemDC中

MemDC.BitBlt(x,y,width,height,&MemDC2,0,0,SRCCOPY); //向草稿绘制第一张图片,x,y,width,height请自行设置

其次,将草稿绘制到屏幕上

dc.BitBlt(0,0,width,height,&MemDC,0,0,SRCCOPY);


(4)释放内存缓冲区
  //绘图完成后的清理  
  MemBitmap.DeleteObject(); 
  MemDC.DeleteDC();  

MemDC2.DeleteDC();

 

 

 

 

下面是一个不使用和使用双缓存的例子

使用双缓存

//CPointptCenter;

         //CRectrect,ellipseRect;

         //GetClientRect(&rect);              //获得窗口客户区的大小

         //ptCenter= rect.CenterPoint();  //获得矩形的中心点,目的是为了确定后面同心圆图像的圆心

 

         //CDCdcMem;                // 创建用于缓冲作图的内存DC对象dcMem

         //CBitmapbmp;                  // 创建内存中存放临时图像的位图对象bmp

         //dcMem.CreateCompatibleDC(pDC);     // 依附窗口DC(窗口对象为pDC),创建兼容内存DC(就是创建一个内存DC,所有图形先画在这上面)

         //bmp.CreateCompatibleBitmap(&dcMem,rect.Width(), rect.Height());// 在兼容内存DC上,创建兼容位图

         //dcMem.SelectObject(&bmp);                 // 将位图选入内存DC

         //dcMem.FillSolidRect(rect,pDC->GetBkColor());// 按照原有背景色填充客户区,否则会成为黑色,同时也使内存DC的背景色保持一致

         绘图操作

         //for(inti = 60; i> 0; --i)

         //{

         //      ellipseRect.SetRect(ptCenter, ptCenter);

         //      ellipseRect.InflateRect(i * 5, i * 5);

         //      dcMem.Ellipse(ellipseRect);         // 在内存DC上绘图,做同心圆图像

         //}

         //pDC->BitBlt(0,0, rect.Width(), rect.Height(),

         //      &dcMem, 0, 0, SRCCOPY);     // 将内存DC上的图像复制到前台pDC,即实际屏幕对象pDC

 

         //dcMem.DeleteDC();      // 删除内存DC

         //bmp.DeleteObject();      // 删除内存位图

不使用双缓存

         CPointptCenter;

         CRectrect,ellipseRect;

         GetClientRect(&rect);

         ptCenter= rect.CenterPoint();

         for(inti=60;i>0;i--)

         {

                   ellipseRect.SetRect(ptCenter,ptCenter);

                   ellipseRect.InflateRect(i*5,i*5);

                   pDC->Ellipse(ellipseRect);

         }

下面的例子是加载两幅图片

 

CBitmap p1,p2;//这是要画的位图,假设已加载好

CDC dc;//这是窗口的DC,假设已加载好

//创建两个临时dcdc1为向窗口绘图的草稿dc2为与源位图连接的dc(实际上dc2也可以用别的方法代替,这只是我的癖好)

CDC dc1,dc2;

dc1.CreateCompatibleDC(&DC);

dc2.CreateCompatibleDC(&DC);

//创建一个临时bitmap作为画布,与dc1连接

CBitmap bm;

CBitmap *Oldbm1,Oldbm2

bm.CreateCompatibleBitmap(pDC,width,height); //长度宽度设置成与绘图面积一样大

dc1.SelectObject(&bm);

dc2.SelectObject(&p1);//dc2与第一张图片链接

dc1.BitBlt(x,y,   width,height,&dc2,0,0,SRCCOPY); //向草稿绘制第一张图片,x,y,width,height请自行设置

dc2.SelectObject(&p2);//dc2与第一张图片链接

dc1.BitBlt(x,y,   width,height,&dc2,0,0,SRCCOPY); //向草稿绘制第二张图片

//将草稿转移至窗口

dc.BitBlt(0,0, width,height,&dc1,0,0,SRCCOPY);

//清理工作

...

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值