zoukankan      html  css  js  c++  java
  • 如何实现双缓冲

    一、什么叫双缓冲

      后备缓冲通过创建一个或多个主缓冲来实现平滑的动画显示,之后用户在不可见的后备缓冲里绘图(具备相同的尺寸和色彩深度的缓冲),只使用一个后备缓冲叫做双缓冲。

    二、用双缓冲技术执行动画流程

    三、创建后备缓冲

      创建后备缓冲的目的是用DirectDraw的方式来实现对双缓冲功能的仿真。

      为了创建一个关联有后备缓冲的主表面,必须创建DirectDraw所谓的复杂表面,步骤如下:

        1、要将DDSD_BACKBUFFERCOUNT加到dwFlags标志字段,向DirectDraw表明DDSURFACEDESC2结构的dwBackBufferCount字段有效,其中含有后备缓冲的数目

        2、将控制标志DDSCAPS_COMPLEX和DDSCAPS_FLIP加到DDSURFACEDESC2结构的特性描述字段ddsCaps.dwCaps上

        3、创建主表面,从它调用IDIRECTDRAWSURFACE7::GetAttachedSurface()以得到后备缓冲

      例:

    DDSURFACEDESC2 ddsd;
    LPDIRECTDRAWSURFACE7 lpddsprimary=NULL;
    LPDIRECTDRAWSURFACE7 lpddsback=NULL;
    
    DDRAW_INIT_STRUCT(ddsd);
    ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
    ddsd.dwBackBufferCount=1;
    
    ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSDCAPS_FLIP;
    
    if(FAILED(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL))){return 0;}
    
    ddsd.ddsCaps.dwCaps=DDSCAPS_BUCKBUFFER;
    
    if(FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps,&lpddsback))){return 0;}
    

      过程如下:

      

    四、将后备缓冲中的画面复制到主缓冲中

      假设你创建的画面是640*480,则需要先锁定后备缓冲,然后将缓存区的指针指向后备缓冲的显示表面,如:

        DDRAW_INIT_STRUCT(ddsd);

        lpddsback->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL);

        UCHAR *back_buffer=(UCHAR*)ddsd.lpSurface;

      此时,你需要判断锁定内存的过程中存储了的内存步长mempitch,如果mempitch等于显示模式的宽度640,则将back_buffer拷贝到primary_buffer:

        memcpy((void*)primary_buffer,(void*)back_buffer,640*480);    //primary_buffer是指向主显示表面

      否则,可以采取逐行拷贝的方式,如:

        memcpy((void*)primary_buffer,(void*back_buffer,640));

        primary_buffer+=mempitch;

        back_buffer+=640;

    五、实现页面切换

      标准动画的循环步骤如下:

        1、清除后备缓存

        2、将场景渲染到后备缓冲

        3、用后备缓冲表面切换掉主表面

        4、锁定在某个帧数率(例如60fps)

        5、重复第1步

      流程图如下:

        

      使用IDIRECTDRAWSURFACE7::Flip(),在交换链中用下一个关联的表面切换主表面

      while(FAILED(lpddsprimary->Flip(NULL,DDFLIP_WAIT)));    //DDFLIP_WAIT表示等待页面切换能够进行为止,第一个参数是DIRECTDRAWSURFACE7类型的指针,用来覆盖切换链,实现到另外一个表面,而不是切换到同主表面相关联的后备缓冲,设为NULL,就是表示切换到同主表面相关联的后备缓冲

  • 相关阅读:
    [官网]清华大学的开源镜像站点 配置方法
    Android MIFARE NFCA源码解析
    Delphi XE8 TStyleBook的使用
    【FireMonkey】StyleBook使用方法
    Delphi第三方组件安装DCU.PAS.DPK.BPL.ActiveX控件
    M1卡说明及使用proxmark3破解方法
    M1卡修改各区块控制位值和数据
    DICOMDIR
    ZentaoPMS 系统的优先级以及修改
    集成禅道和svn
  • 原文地址:https://www.cnblogs.com/zjzsky/p/3410564.html
Copyright © 2011-2022 走看看