双缓冲技术 directdraw

双缓冲技术

 

在离屏缓冲绘制图像,然后将其拷贝到显示表面的处理过程被称作双缓冲技术。

实现:额外的一块同主DirectDraw表面具有同样尺寸的内存。并在这块内存上画每一帧动画之后拷贝双内在到主显示表面。

如:申请640X480X8的内存
UCHAR *double_buffer = (UCHAR *) malloc (640*480);
或者
UCHAR *double_buffer = new UCHAR[640*480];

实现:让后备缓冲显示出来,可以把后备缓冲拷贝到主显示页面代码如下:

复制代码
DDSURFACEDESC2 ddsd;  // directdraw 表面结构说明

LPDIRECTDRAWSURFACE7 lpddsprimary 
=  NULL; // 主表面指针

LPDIRECTDRAWSURFACE7 lpddsback 
=  NULL; // 后备缓冲指针

DDRAW_INIT_STRUCT(ddsd);
// 初始化ddsd

// 蓝色的表示ddsd的dwBackBufferCount字段有效
ddsd.dwFlags  =  DDSD_CAPS  |  DDSD_BACKBUFFERCOUNT; 

ddsd.dwBackBufferCount 
= 1 ; // 表示一个后备缓冲页面

ddsd.ddsCaps.dwCaps 
=  DDSCAPS_PRIMARYSURFACE  |  DDSCAPS_COMPLEX  |  DDSCAPS_FLIP; // 步骤第二条

if  (FAILED(lpdd -> CreateSurface( & ddsd,  & lpddsprimary, NULL);
return ( 0 ); // 创建主表面 

ddsd.ddsCaps.dwCaps 
=  DDSCAPS_BACKBUFFER;

// 主表面得到后备缓冲
if  (FAILED(lpddsprimary -> GetAttachedSurface( & ddsd.ddsCaps,  & lpddsback)))
return ( 0 );

如果想操控后备缓冲信息
//  初始化ddsd
DDRAW_INIT_STRUCT(ddsd);

lpddsback
-> Lock(NULL,  & ddsd, DDLOCK_SURFACEMEMORYPTR |  DDLOCK_WAIT, NULL); // 锁定后备缓冲

// 这里可以对它进行读写操作

lpddsback
-> Unlock(NULL); // 解锁
复制代码
离屏表面有两类
A) 后备缓冲 (Back Buffer) 当你创建主表面进也创建它们。目的是用DirectDraw的方式来实现对双缓冲功能的仿真。
读写会非常快。 可以和主表面进行页面切换。
创建一个关联有后备缓冲的主表面, 必须创建DirectDraw所谓的复杂表面(ComplexSurface) 创建步骤如下:
1先将 DDSD_BACKBUFFERCOUNT加到dwFlags标志字段,向DirectDraw表明DDSURFACESC2
结构的dwBackBufferCount字段有效,其中包括后备缓冲数目。
2再将控制标志DDSCAPS_COMPLEX和DDSCAPS_FLIP加到DDSURFACEDESC2结构的特性描述
字段ddsCaps.dwCaps上。
3最后像通常一样建立表面,用IDIRECTDRAWSURFACE7 :: GetAttachedSurface()得到后备缓冲。
 
例如:
复制代码
DDSURFACEDESC2 ddsd;  // directdraw 表面结构说明

LPDIRECTDRAWSURFACE7 lpddsprimary 
=  NULL; // 主表面指针

LPDIRECTDRAWSURFACE7 lpddsback 
=  NULL; // 后备缓冲指针

DDRAW_INIT_STRUCT(ddsd);
// 初始化ddsd

// 蓝色的表示ddsd的dwBackBufferCount字段有效
ddsd.dwFlags  =  DDSD_CAPS  |  DDSD_BACKBUFFERCOUNT; 

ddsd.dwBackBufferCount 
= 1 ; // 表示一个后备缓冲页面

ddsd.ddsCaps.dwCaps 
=  DDSCAPS_PRIMARYSURFACE  |  DDSCAPS_COMPLEX  |  DDSCAPS_FLIP; // 步骤第二条

if  (FAILED(lpdd -> CreateSurface( & ddsd,  & lpddsprimary, NULL);
return ( 0 ); // 创建主表面 

ddsd.ddsCaps.dwCaps 
=  DDSCAPS_BACKBUFFER;

// 主表面得到后备缓冲
if  (FAILED(lpddsprimary -> GetAttachedSurface( & ddsd.ddsCaps,  & lpddsback)))
return ( 0 );

如果想操控后备缓冲信息
//  初始化ddsd
DDRAW_INIT_STRUCT(ddsd);

lpddsback
-> Lock(NULL,  & ddsd, DDLOCK_SURFACEMEMORYPTR |  DDLOCK_WAIT, NULL); // 锁定后备缓冲

// 这里可以对它进行读写操作

lpddsback
-> Unlock(NULL); // 解锁
复制代码
 
页面切换:前面有了主表面和后备缓冲表面,进行页面切换后就能实现动画了。

1清除后备缓冲。(初始化)
2将场景渲染到后备缓冲。
3用后备缓冲切换掉主显示表面。
4锁定帧速率。
5重复第一步。
用下面的函数来对关联表面和主表面进行切换。
 
HRESULT Flip (LPDIRECTDRAWSURFACE7 lpDDSurfaceTargetOverride, DWORD dwFlags);其中lpDDSurfaceTargetOverride

是个高级参数,用来覆盖切换链,实现切换到另一个表面,而不是切换到同主表面相关的后备缓冲,这里值为NULL。

后面的dwFlags是控制标志见p248
默认是1。这些要在DDCAPS结构中设置了DDCAPS2_FLIPINTERVAL后才起作用。
 
例如: 
       lpddsprimary->Fliy(NULL, DDFLIP_WAIT);
注意:切换之前主表面和后备缓冲表面都要解锁。代码例子p249

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值