荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Peter (小飞侠), 信区: Program
标  题: DirectX5.0游戏编程指南(一)
发信站: BBS 荔园晨风站 (Thu Jan 21 22:34:19 1999), 转信


DirectX5.0最新游戏编程指南
综述篇
武汉 朱春喜 & 吴佳鲜

    对于众多的游戏制作者来说,Microsoft的DirectX 5的推出不啻
是一个极好的消息。它包含了编制下一代计算机游戏和多媒体应用程序
的最新技术和工具,为广大的程序员提供了一整套的应用程序接口API,
使程序员能够设计高性能实时的应用程序。DirectX使运行在Microsoft
Windows操作系统下的游戏比运行在 MS-DOS操作系统下的游戏具有更高
的性能的更好的交互性,甚至比专用的游戏机也不遑多让。
    Microsoft开发DirectX的首要目的就是要提高Windows环境下游戏开
发的容易性。在此之前,个人电脑上的大部分游戏都是基于MS-DOS的,游
戏开发人员必须针对不同的硬件接口卡编制不同的程序,尽管代码类似,
但不可避免存在许多的重复劳动。利用DirectX, 游戏开发人员就可以获
得DirectX的硬件独立性的优点,同时又可以直接访问硬件。DirectX的最
主要的目标就是提供MS-DOS中直接的硬件访问特性,同时去掉个人电脑中
再添加新的硬件时所带来的硬件识别问题。
    因为硬件的升级是不可避免的,所以,DirectX实际上也提供了另一
种即插即用的方法。因此,利用DirectX可以开发出高性能实时的应用程序,
可以直接访问计算机中的硬件和将来系统中回具有的硬件设备。DirectX在
硬件和应用之间提供了一致的接口以减少安装和配置的复杂性,并且使硬件
的利用达到最优。利用DirectX提供的接口,程序员能充分利用硬件的特性
而不需要考虑其具体细节。一个优秀的基于Windows的高性能游戏应该能够
利用系统的如下技术:
.为提高性能而专门设计的加速卡
.即插即用PnP(Plug and Play)
.内嵌于Windows的通信服务,包括DirectPlay

   DirectX 5包括七个部分,下面对各部分作以简要说明。
(1).DirectDraw  通过支持访问屏外显示内存中位图的软硬件加速技术,快
    速直接存取,利用硬件的位块传输和缓冲区翻转功能。
(2).DirectSound 提供软硬件声音混合和录音再生功能。
(3).DirectPlay   使得游戏在调制解调器和网络之间的连接更加简单方便。
(4).Direct3D    提供了高级保留模式(Retained-Mode)接口和低级即时
    模式(Immediate-Mode)接口。前者允许程序很容易地完成一个完全
    的三维图形系统,后者使得程序能完全控制着色管道。
(5).DirectInput   提供了基于Windows游戏的输入的API和驱动程序,它
    不仅支持目前的键盘、鼠标和操纵杆,也支持将来的基于Windows的输
    入设备。
(6).DirectSetup   提供了DirectX的一次性安装过程。
(7).AutoPlay     它是Windows 95的特性,当你将光盘放入光驱时,它能
    自动运行安装程序或游戏。事实上,AutoPlay也是Microsoft Win32 API
    的一部分,而不是仅存在于DirectX SDK中。.

    通过查询各种DirectX对象接口,你可以检测系统中安装的是DirectX的
哪个版本,DirectX  SDK中的范例文件GetDXVersion.cpp中的GetDXVersion
函数可以完成这一任务。该函数创建了一些关键的DirectX对象──一个
DirectDraw对象、一个DirectDrawSurface对象和一个DirectInput对象──
来检测安装在系统中的DirectX的版本。如果系统中安装了老版本的
DirectX SDK,必须确保不要包含它的INCLUDE和LIB路径,使用DirectX 5头
文件编译后的代码同DirectX 3的库链接后将会出现不可预知的错误。

    因为C++语言更能够对计算机硬件作直接的访问,所以DirectX采用了
C++语言作为开发的主语言。而DirectX又是专门为Visual C++设计的,所以
编写DirectX程序最好能在Visual C++下进行。当然Borland C++5.0也没问题,
只是配置有些不同罢了,下面将会提到这一问题。为了降低编程的难度,
一些公司也针对DirectX开发了运行在不同编程环境中的控件,
如Arakelian Soft公司的ActiveX控件DirectStudio98 for Visual Basic5.0、
Tegosoft公司的TegoSoft ActiveX for Visual Basic、
还有John Pullen、Paul Bearne和Jeff Kurtz开发的运行在Delphi下的
Delphi Games Creator等。考虑到兼容性问题,最好还是能使用Visual C++。

一、DirectX和部件对象模型COM

1.1、   部件对象模型COM(Component Object Model)
    DirectX中的大部分API都由基于COM的对象和接口组成。COM是接口重利用
的基于对象的系统的基础,是COM编程的核心模型,它也是一种接口规范。
在操作系统级别上,它又是一个对象模型。
    许多DirectX API都创建为COM对象的实例。你可以将一个对象看做一个
黑盒子,对象通过接口与对象通信,通过COM接口发送给对象或从对象接收的
命令称为方法。例如,IDirectDraw2::GetDisplayMode方法是通过IDirectDraw2
接口从DirectDraw对象获得当前的显示模式。对象在运行时可以同其他对象
捆绑在一起,并且能够使用这些对象的接口。如果你已知道某个对象是COM对象,
并且知道该对象支持的接口,你的应用程序或其他对象就能够确定第一个对象所
能执行的服务。所有COM对象都继承的一个方法是Query接口方法,它让你确定
一个对象支持的接口和创建这些接口的指针。

1.2、IUnknown 接口
    所有的COM 接口都由一个称为Iunknown的接口衍生而来,该接口为DirectX
提供了对象生存期的控制和操作多接口发能力。Iunknown含有三个方法:

        .AddRef  当一个接口或另一个应用捆绑到一个对象上时,就使用AddRef
                 方法将该对象的索引值加1。
        .QueryInterface  通过指向特定接口的指针查询对象所支持的特性。
        .Release         将对象的索引值减1,当索引值变为0时,该对象就从
                 内存中释放。

    其中AddRef和Release方法负责维护对象的索引值。例如,如果创建一个
DirectDrawSurface对象,该对象的索引值就被设定为1,每次当有一个函数返回
该对象的指针时,该函数必须通过返回发指针调用AddRef方法将该对象的索引值
加1。每一个AddRef的调用都必须有一个Release的调用与其对应。当对象的索引
值达到0时,该对象就被撤消,该对象的所有接口都不可再用。
    QueryInterface方法测定一个对象是否支持指定的接口,如果支持,
QueryInterface就返回指向该接口的指针。然后你可以使用该接口包含的方法同
对象通信。如果QueryInterface成功地返回接口的指针,它会自动调用AddRef
方法增加对象的索引值。在撤消接口指针之前必须调用Release来减少对象的索引值。

1.3、   DirectX COM 接口
    DirectX中的接口是用相当基本的COM编程创建的。表征了设备的对象的每个接口
都由IUnknown COM接口派生而来,如IDirectDraw2、IDirectSound和IDirectPlay都
是这样。基本对象的创建工作由动态链接库DLL中的特殊函数来处理。
    典型的情况是,DirectX对象模型为每个设备提供了一个主对象。其它支持服务
的对象由主对象派生而来。例如,DirectDraw对象就表征了显示适配器。你可以利用
DirectDraw来创建表征显示内存的DirectDrawSurface对象和表征硬件调色板的
DirectDrawPalette对象。同样道理,DirectSound对象表征了音频卡,利用它可创建
表征音源的DirectSoundBuffer对象。
    除了能够产生子对象外,设备的主对象还能测定它所表征的设备的性能,如屏幕
的大小和颜色数、声卡是否支持波表合成等。

1.4、   C++和COM 接口
    对C++程序员来说,COM接口就象一个抽象的基类。在C++的基类中,所有的方法
都定义为纯虚的,这就意味着没有任何代码同方法关联在一起。纯虚的C++函数和COM
接口都使用一种称为虚表(vtable)的设备。一个虚表包含了应用于所给接口的所有
函数的声明。如果你想让程序或对象使用这些函数,可以先用QueryInterface方法检
查对象存在的接口,获取该接口的指针,调用QueryInterface后,应用或对象实际上
就从对象中接收到了虚表的指针,通过该指针就可以调用应用于该对象的所有接口方法。
    COM对象和C++的另一个相似之处是方法的第一个参数就是接口或类的名字,C++
中称为this参数。因为COM对象和C++对象是完全二进兼容的,编译器就将COM接口同C++
抽象类同样处理,并且具有相同的语法,这会使得代码简单一些。

1.5、   获取新的接口
    部件对象模型不是通过改变存在的接口中的方法而是通过扩展包含有新特性的新接
口来更新对象的功能。在保留已有的接口状态的情况下,COM对象能够自由扩展服务并
维持同旧的应用兼容。DirectX部件遵循这一原则,例如,DirectDraw部件支持
IDirectDrawSurface 接口的三个版本: IDirectDrawSurface、IDirectDrawSurface2
和IDirectDrawSurface3。要想利用新接口提供的特性,你必须调用对象的
IUnknown::QueryInterface方法,指定欲获取的接口的全局统一标识GUID
(globally unique identifier)。接口的GUID在相关的头文件中声明。
下面的例子说明了如何查询一个新的接口:
    LPDIRECTDRAW    lpDD1;
    LPDIRECTDRAW2   lpDD2;

    ddrval = DirectDrawCreate( NULL, &lpDD1, NULL );
    if( FAILED(ddrval))
        goto ERROROUT;

    // Query for the IDirectDraw2  Interface
    ddrval = lpDD1->Query接口(IID_IDirectDraw2, (void **)&lpDD2);
    if( FAILED(ddrval))
        goto ERROROUT;

    // Now that we have an IDirectDraw2, release the original Interface
    lpDD1->Release();
    新的接口不支持以前版本接口所提供的方法的情况极少,IDirect3DDevice2
接口刚好是这样的一个接口。如果你的应用需要早期版本的接口提供的特性,你
可以利用老的接口的GUID,使用上述例程来查询该接口。

1.6、   用C存取COM对象
    使用C语言也可以调用任何COM接口方法。用C语言调用一个接口方法需要主
要两件事:
        .方法的第一个参数始终是已经创建的调用该方法的对象(即this)
        .接口中的每个方法都通过对象虚表的指针来引用
下面的例子使用C语言调用IDirectDraw2::CreateSurface方法创建一个同一个
DirectDraw对象关联的表面:

ret = lpDD->lpVtbl->CreateSurface (lpDD, &ddsd, &lpDDS,
      NULL);

    其中 lpDD参数是同新表面关联的DirectDraw对象,同时,该方法填充一
个描述表面(Surface)的结构&ddsd,返回指向新接口&lpDDS的指针。调用
IDirectDraw2::CreateSurface方法,首先要指向该DirectDraw对象的虚表,
然后获取虚表中的方法。方法中提供的第一个参数是已经创建的DirectDraw
对象的索引。下面的代码说明了C和C++对COM对象方法调用的不同之处:
ret = lpDD->CreateSurface(&ddsd, &lpDDS, NULL)

二、DirectX 5中的新内容
    大家知道, DirectX 5是DirectX的最新版本,在此之前,Microsoft曾发布过
DirectX、DirectX2、DirectX3(没有DirectX4)。显然,DirectX 5比DirectX3提
供了更多的功能和服务,不过,利用DirectX3 API写的程序不需要修改就可以成功
地编译和运行。下面是DirectX5和DirectX3的主要不同之处:

2.1、DirectDraw
    DirectDraw扩展了新的视频端口能力,允许应用程序控制从硬件视频端口传送
到显示内存中的DirectDraw表面的数据流。另外,DirectDraw 硬件仿真层HEL
(Hardware Emulate Layer)能够利用Pentium MMX处理器提供的加速性能。
DirectDraw在你第一次创建一个表面时会检测处理器是否MMX处理器,在非奔腾处理
器的计算机上,该测试会导致调试器报告出一个事件,该事件不会影响程序的性能
和稳定性。DirectDraw支持比主表面(Primary Surface)更宽的屏外表面
(Off-screen Surface),只要硬件允许,你可以创建足够宽的表面。
    DirectDraw支持高级图形端口AGP(Advanced Graphics Port)特性。在一个
AGP设备系统,你可以在非本地显示内存创建表面。DDSCAPS结构支持标准(本地)
显示内存和AGP(非本地)显示内存之间不同的标志。DirectDraw 可以向非本地显
示内存位块传输DDCAPS结构包含的成员信息。

2.2、DirectPlay
    DirectPlay包含了一个新的接口IDirectPlay3,除了新的方法之外,其它同
IDirectPlay2完全相同。同样地,IDirectPlayLobby2也是IdirectPlayLobb
y的升级版本。DirectPlay的新功能包括通过创建连接快捷方式来隐藏服务提供者
(Service Provider)对话的能力,还可以保持可用会话的更新列表,应用
SetSessionDesc方法更好地支持口令保护会话,支持保密服务连接及使用
CoCreateInstance直接创建多个DirectPlay对象。

2.3、DirectSound
    DirectSound 包含了一个新的接口IksPropertySet,使得支持由声卡和相关
驱动程序提供的扩展服务。基于COM的函数DirectSoundCapture也是新的,它可以
直接访问驱动程序。

2.4、Direct3D
    Direct3D即时模式(Immediate Mode)现在支持Drawing Primitive,而不必
直接在缓冲区中工作。Direct3D保留模式(Retained Mode)支持插值使你能够调
和颜色,平滑地移动物体,变形网格,并且执行许多其他的变换。保留模式也支持
渐进网格,即允许你先开始于一个粗糙的网格,然后再细化它。

5、DirectInput
    DirectInput提供了操纵杆的COM接口,同时还提供了键盘和鼠标等力反馈装
置的COM接口。

6、DirectSetup
    DirectSetup现在包含了更多的用户接口定制能力,而这是由一个回调函数提
供的。该回调函数将当前的安装状态传递给安装程序,你可以通过定制的用户接口
利用这一信息来显示安装状态。另外,DirectSetup提供了多个玩家的游戏的方法,
在游戏中,玩家可以使用DirectPlayLobby从注册表中去掉注册信息。

6、AutoPlay     AutoPlay同DirectX3中一样,未做变动。

--
※ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.1.3]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店