现在的位置: 首页 > 综合 > 正文

VC界面绘制双缓存

2013年08月28日 ⁄ 综合 ⁄ 共 1458字 ⁄ 字号 评论关闭

转载请注明原文网址: 

http://www.cnblogs.com/xianyunhe/archive/2011/11/20/2255811.html

1、闪屏的问题

在GDI的绘图系统中,每调用一次区域绘图操作,如FillRect、BitBlt等,图形显示系统就会在屏幕中对指定的区域进行一次刷新操作。如果频繁的进行区域绘制操作的操作的话,我们就会发现,屏幕会出现闪屏。

使用下面的代码对闪屏的问题进行测试,在XP系统闪屏尤其严重,在Win7系统,闪屏问题有所改善。Win7系统在绘制效率上有所提升。

?
void CDoubleBufferView::DrawDirect(CDC*
pDC)
{
    ASSERT_VALID(pDC);
 
    /*用渐变色粉刷背景*/
    CRect
rect(0,0,0,0);
    CSize
szTotal = GetTotalSize();
    for (int i
= 0; i <= szTotal.cy; i++)
    {
        rect.left
= 0;
        rect.right
= szTotal.cx;
        rect.top
= i*10;
        rect.bottom
= (i+1)*10;
        pDC->FillSolidRect(&rect,
RGB((i*10)%255,0,0));
    }
 
    /*绘制图片*/
    CDC
dcPic;
    dcPic.CreateCompatibleDC(pDC);
    CBitmap
bmpImport;
    bmpImport.LoadBitmap(IDB_BITMAP1);
    CBitmap*
pOldBmp = dcPic.SelectObject(&bmpImport);
    BITMAP
bitmap;
    bmpImport.GetBitmap(&bitmap);
    int iWidth
= bitmap.bmWidth;
    int iHeight
= bitmap.bmHeight;
    pDC->BitBlt(0,
0, iWidth, iHeight,
        &dcPic,
0, 0, SRCCOPY);
    dcPic.SelectObject(pOldBmp);
 
    /*释放资源*/
    bmpImport.DeleteObject();
    dcPic.DeleteDC();
}

 

2、双缓存

产生闪屏的原因是类似于多进程之间的通信问题,每次DC的绘图操作,都要把相关的显示数据发送到显卡,显卡处理后,在显示器上显示。借鉴提升多线程之间的通信效率的解决方法,可通过减少与显卡之间的交互次数来提升绘制的效率。这也就是双缓存的思路。双缓存的原理是先把更新操作中所有绘制数据先写入内存,然后再调用BitBlt或StretchBlt一次性的把所有数据发送到显卡中。

用一个比喻来说,没有用双缓存就像老师讲课时在黑板上使用粉笔写板书,学生能看到老师写板书的整个过程,如果把黑板看做是一个屏幕的话,老师在写板书的过程,就是一个闪屏的过程。

使用了双缓存,就像老师采用了多媒体教学,老师就可以提前在家把板书用PPT做好,上课时只要一页一页的翻PPT就可以了,学生们是看不到PPT制作的过程,也就会有闪屏的问题了。

可采用了如下代码来实现双缓存。

?
void CDoubleBufferView::DrawWithBufferInefficient(CDC*
pDC)

抱歉!评论已关闭.