你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
在C++ Builder中进行DirectX编程(上)
 

动画的实现

动画是游戏程序不可缺少的部分,也是游戏与玩者间交互的主要渠道,DirectX提供了高速动画实现的解决方案。类似在DOS下用TC开发图形程序时采用多页面切换实现动画一样,DirectDraw也是通过在后台绘画,然后切换显示页面的技术来实现平滑动画。

一、动画实现技术

1创建复合切换图面

所谓复合图面即在创建主图面时,增加COMPLEX等描述,使得主图面拥有一个或多个切换页面,形成页面翻转链。最简单情况是有一个显示页面、一个后台切换页面,程序只在后台切换页面上绘图,当下一帧图形在后台切换页面生成后,进行一次切换(Flip),使后台切换页面与显示页面交换页面指针(只交换指针,使后台切换页面的指针永远指向后台切换页面,程序始终在后台绘制图形,无需考虑页面指针是否变化),重复上述过程,即可产生动画祯,产生动画。

2 动画帧的绘制

如果您没有创建复合图面,那么绘图工作就必须在显示页面上进行了,这样,在绘制少量图形和性能比较好的计算机上,可能不会有明显的问题,但如果需要绘制图形复杂度高、数据量大时,图形绘画和更新的过程就明显地表现出来,动画出现抖动现象。但采用在后台切换页面绘制图形,当一个帧绘制完成后,一次性切换为显示页面,由于切换时间很短(与屏幕刷新同步),就不会出现闪烁现象。

每一帧图形的绘制是通过位转换操作来完成的,即把不同后台图面的数据按需要的组合传递到后台切换页面。位转换操作可以使用Windows提供的BitBlt函数完成,但其速度太慢了,DirectDrawDirectDrawSurface对象提供了BltBltFast两个方法来实现快速的位转换操作。

3 透明

在进行位转换操作时往往会涉及图形叠加的问题,例如:首先将一幅背景图绘画在主图面的后台切换页面上,然后需要将一个精灵画在该页面的中间,由于精灵图形定义是一个矩形,所以必须使不应该显示的位置产生透明而显示背景图形。如图2.3中所示,是否透明所形成不同的结果。

2.3中有四张图,(A)图为精灵图形的定义,图形为一矩形框,背景色为白色;(B)图为背景;(C)图为未进行透明处理背景与精灵叠加的结果,可以看到精灵的矩形框遮挡了背后的背景图形;(D)图为进行透明处理背景与精灵叠加的结果,精灵原始图形中白色部分没有挡住背景,使精灵与背景能够很好地融合。

    DirectDraw的位转换中实现透明并非十分复杂,只要事先指定精灵图形所在后台图面的透明颜色键(dx3中为白色),然后在位转换时声明以透明方式处理即可。如何确定颜色键值是稍微麻烦的问题,我们以后再详细讨论。

 

 

(A)精灵      (B)背景               (C) 不透明叠加           (D)透明叠加

2.3 精灵与背景叠加非透明和透明处理的不同效果

4 图面切换及需要防止的撕裂现象

显示器的扫描刷新是有一定周期的,如果程序在扫描过程中切换页面,就会造成屏幕上一部分是前一帧的图象,另一部分是后一帧的图象,如图2.4所示,主图面的显示页面上圆圈在中间,后台切换页面上圆圈向右移动了一些,正确的动画是当页面切换后,源泉从屏幕中间向右运动了一段距离,但由于切换发生在屏幕刷新到一半的时间,屏幕上半部分仍是初始图象,而屏幕下半部分则显示出新图形,使圆圈上下错位,形成撕裂现象。

     (A) 显示页面    (B)后台切换页面      (C)屏幕刷新一半   (D)页面切换后

                                                              另一半刷新

2.4 页面切换产生的撕裂现象

    为了解决撕裂现象,就必需保证在屏幕刷新周期完成,下个周期未开始之前进行页面切换操作,所以Flip方法总是需要等待一些时间。当后台切换页面帧完成后,程序不能立即将它切换为显示页面,而需要等到下一屏幕刷新之前进行,为了充分使用CPU和系统资源,有时使用多个后台切换页面,并利用等待屏幕刷新的时间多绘制一些帧(或帧的部分图形),以提高系统效率。

5示例程序dx3的运行过程介绍

2.5dx3程序窗口,程序开始时首先按下执行按钮,dx3将创建DirectDraw对象并设置系统为800*600*256色全屏显示方式;按下创建主图面及复合切换图面按钮创建一个包含一个显示页面和一个后台切换页面的复合主图面;接下来按创建后台图面并装入图形按钮,dx3创建一个后台图面,此后台图面将装入图形文件spirit.bmp,如图2.6,该图由12100*104的精灵动画帧组成,所以该图面的尺寸为400*312,图形的背景色为白色(背景色可选择较少使用颜色,如绿色、粉红);下一步是必需获得主图面后台切换页面(后端缓冲区)的指针,否则程序将无法在后台绘制动画帧,也就不能实现切换操作,所以要按下获得主图面后端缓冲区指针按钮;现在最下面的三个按钮都可以使用了,它们分别采用不同的方法实现动画,以便比较动画的效果。主图面直接绘图动画演示是用BitBlt函数将动画图形直接在显示页面上(屏幕左上方)绘制,如果在速度慢的计算机上,可以看到闪烁现象;后端缓冲动画演示是采用帧切换方式实现动画的,由于在后台切换页面是用BitBlt函数绘图,先复制整个屏幕背景,再叠加绘制精灵动画下一帧图形,待屏幕刷新下一个周期开始前,切换显示页面;BltFast方法的透明动画也采用后端缓冲动画技术,不同的是在位转换操作时采用DirectDrawSurfaceBltFast方法,从而实现透明和高速动画,精灵从屏幕左上方向右移动。

 

 

 

 

 

 

 

 

 

 

 

 

 

2.5 dx3精灵动画运行界面

 

 

 

2.6 精灵动画

 

从三种动画演示可以看出,第二种方法动画                       

速度较慢,这主要是低效率的GDI造成的,第三种动画速度相对很快,因此dx3程序不得不在动画帧之间加入150毫秒的延迟,这种现象在装有directX7.0的系统上更为明显。

    dx3中没有使用Blt方法,因为它比较复杂,今后我们将对位转换操作的BltBltFast方法进行专门的介绍。

6dx3的编程实现

1创建DirectDraw对象并设置800*600*256色显示模式

    此部分内容与在2.1中已经介绍,这里不再重复。需要说明的是dx3示例程序把显示方式的色彩深度设为8位(256色),是因为透明处理得比较好,读者可以自己修改此示例程序,分别设置16位和24位色    `彩深度,会发现有异常情况出现,我们在这里暂不研究此方面的原因。有一点是肯定的,色彩深度越深,动画的速度就越慢。也许您会觉得dx3精灵动画不够流畅,这与我们使用动画图形的帧的数量和质量有关。

2创建主图面和复合切换图面

复合切换型的主图面是在CreateSurface时实现的,即在DDSURFACEDESC结构中设置ddsCaps.dwCaps时要加入DDSCAPS_COMPLEXDDSCAPS_FLIP标志,另外还需给dwBackBufferCount定义后台缓冲区(后台切换页面)的数目,由于在dx3中只使用一个后台缓冲页面,所以此项设置为1。如以下示例片段:

    ddsd.dwSize=sizeof(ddsd);

    ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT;

    ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE

                        |DDSCAPS_FLIP

                        |DDSCAPS_COMPLEX;

    ddsd.dwBackBufferCount=1;

    lpDD2->CreateSurface(&ddsd,&lpDDPrimary,NULL);

3创建后台图面并装入图形(与dx2中相同,略)

4获得主图面后台切换图面(后台缓冲)指针

既然主图面有显示和后台切换2个页面,因此就应该有2个分别指向前、后台切换页面的指针,通过CreateSurface方法得到的lpDDPrimary只是显示页面的指针,所以需要用GetAttachSurface方法获得后台切换页面的指针,以便图形绘制到后台。GetAttachSurface方法的格式为:

HRESULT IdirectDrawSurface::GetAttachSurface(LPDDSCAPS lpDDScaps,

LPDIRECTDRAWSURFACE FAR *lpDDAttachedSurface)

其中:参数lpDDScaps是一个DDSCAPS结构,需要强调的是,在调用GetAttachSurface方法之前,该结构的dwCaps必需设置为DDSCAPS_BACKBUFFER(前端显示页面的标志为DDSCAPS_FRONTBUFFER);如果执行成功,则参数lpDDAttachedSurface将返回指向后台切换页面的指针。

5主图面直接绘图动画演示

    采用BitBlt函数,从后台图面上连续将精灵动画的每一帧绘画到主图面显示页面的(0,0)(99,103)的矩形区域内。由于不需要恢复背景图形、绘图工作量小的缘故,此部分程序比较简单,且运行速度比较快,需要加入延时Sleep(150)

6后端缓冲动画演示

后台缓冲动画是使用一个复合切换图面作为绘图板,首先将当前可见屏幕复制到切换图面,再将精灵动画帧绘制在切换图面的(0,0)处,最后进行图面切换,新的图面一次性显示出来。

7BltFast方法的透明动画

Blt方法相对BltFast方法要慢一些,但允许更多的控制,如:放缩、镜像、旋转、剪切等,而BltFast注重的是速度。另外,BltBltFast都提供了透明控制,使精灵周围的背景都能正常显示出来。

dx3最后的示例中我们采用BltFast实现走动的精灵动画。该方法的格式为:

IdirectDrawSurface::BltFast(DWORD dwX,DWORD dwY,

                        LPDIRECTDRAWSURFACE lpDDSurface,

                        LPRECT lpRect,

                        DWORD dwTrans)

其中:参数XY为图形绘制目标坐标;lpDDSurface为位转换操作源图面;lpRect是一个结构类型,指定源图面需进行为转换操作的矩形,描述为struct RECT {LONG left,LONG top,LONG right,LONG bottom}dwTrans是控制标志,可以使用的控制标志有

DDBLTFAST_DESTCOLORKEY  使用目标颜色值

DDBLTFAST_SRCCOLORKEY   使用源颜色值(示例中使用实现透明动画)

DDBLTFAST_NOCOLORKEY    不进行透明位转换操作

DDBLTFAST_WAIT           在为转换器建立或出现错误之前自动等待,不返回

DDBLTFAST_WAITCPU及显示卡协处理器的异步操作效率有关,在位转换操作应加上此控制标志。

如果位转换操作需要透明处理,则必需指定颜色键值,即:对某种颜色或某个颜色范围进行透明处理。颜色键值可以直接给出或的从源图面获取,在dx3中采用的是获取源图面(0,0)点的颜色值,并将它设置为图面的颜色键,具体步骤是:

1         锁定源图面;

2         获得源图面 (0,0)点的颜色值并存放到dw变量;

3         根据需要调整dw

4         对源图面解锁;

5         设置DDCOLORKEY结构的dwColorSpaceLowValuedwColorSpaceHighValuedw的值;

6         SetColorKey方法设置源图面颜色键值。

设置颜色键值方法:

IdirectDrawSurface::SetColorKey(DWORD dwFlags, LPDDCOLORKEY lpDDColorKey);

其中:参数dwFlage是控制标志,可以取以下值:

DDCKEY_COLORSPACE    图面包含某颜色范围

DDCKEY_DESTBLT        结构中包含位转换操作的目标颜色值

DDCKEY_DESTOVERLAY  结构中包含用于覆盖操作的目标颜色值

DDCKEY_SRCBLT         结构中包含位转换操作的源颜色值(dx3示例使用此标志)

DDCKEY_SRCOVERLAY    结构中包含用于覆盖操作的源颜色值

    参数lpDDColorKeyDDCOLORKEY结构指针。

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089