如何实现双缓冲

一、什么叫双缓冲

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

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

 

三、创建后备缓冲

  创建后备缓冲的目的是用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,就是表示切换到同主表面相关联的后备缓冲

 

 

 

 

 

posted @ 2013-11-06 14:56  LOSER Z  阅读(2303)  评论(0编辑  收藏  举报