GDI 闪烁消除 双缓冲(Double buffer)

86 篇文章 0 订阅
48 篇文章 0 订阅

   如果你真正实现动画的话,你会发现画面一闪一闪的,十分的不爽。 很多人都会怪到GDI头上,他们又会骂MS,说GDI太慢了。其实非也(不是指MS不该骂,呵呵),任何直接写屏幕的操作都会产生闪烁,在DOS下 直接写显存或者用DirectDraw API直接写Primary Surface都会闪烁,因为你每个更新显示的操作都会被用户马上看到(因为垂直回扫的原因, 或许会有延迟)。

 

  消除闪烁最简单也是最经典的方法就是双缓冲(Double buffer)。所谓的双缓冲其实道理非常简单,就是说我们在其它地方(简单的说就是不针对屏幕,不显示出来的地方)开辟一个存储空间,我们把所有的动画都要渲染到这个地方,而不是直接渲染到屏幕上(针对屏幕的存储区域)。在GDI中,直接针对屏幕就是窗口DC,”不可见的地方”一般可以用Memory DC。在把所有动画渲染到后台缓冲之后,再一下次整体拷贝到屏幕缓冲区!

在纯软件2D图形引擎中,双缓冲一般意味着在内存中开辟一个区域用来存储像素数据

 

view类里面创建CDC对象m_ImageMemo,指针m_pDC,创建二者关联,并且通过一个窗口大小的位图来确定内存DC即m_ImageMemo的大小; 将m_ImageMemo以引用的方式传到要画的其他类里面:假设类test1, test2类,类的成员函数里面的画操作只是m_ImageMemo.BitBlt,最后在view类面只要将m_ImageMemo内容拷贝到屏幕上面就可以了,

 

具体作法:

1.在view类里面创建窗口大小的内存DC m_ImageMemo;

 

void CGameView::OnInitialUpdate()
{
    CView::OnInitialUpdate();

    CRect rc;
    GetClientRect(rc);
    m_ImageMemo.CreateCompatibleDC(m_pDC);            //创建二者关联;
                                                    
//最多只能一次;
    CBitmap bmp;
    bmp.CreateCompatibleBitmap(m_pDC,rc.Width(),rc.Height());
    m_ImageMemo.SelectObject(&bmp);
    bmp.DeleteObject() ;
}

其中函数OnInitialUpdate()手动添加,

 

2.以引用的形式传到test1::Draw(&m_ImageMemo), test2::Draw(&m_ImageMemo);

3.最后将内存DCm_ImageMemo的内容拷贝到屏幕上面,一次性显示;

    CRect rc;
    GetClientRect(rc);
    ASSERT(m_pDC != NULL);
    //将所有内容拷贝到屏幕上去;
    m_pDC->BitBlt(0,0,rc.Width(),rc.Height(),&m_ImageMemo,0,0,SRCCOPY);

其中操作2,3都在OnTimer里面,

这样子即使画很多内容,也不会产生刷屏的。

 

获取更多帮主请关注小程序

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值