CSDN博客

img holyfire

DirectX5.0最新游戏编程指南

发表于2001/4/13 10:12:00  1311人阅读

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)接口。前者允许程序很容易地完成一个完
全的三维图形系统,后者使得程序能完全控制着色管道。
.DirectInput   提供了基于Windows游戏的输入的API和驱动程序,它不仅支持目前的键盘、鼠标和操纵杆,也支持将来的基于Windows的输入设备。
.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也是IdirectPlayLobby的升级版本。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中一样,未做变动。

0 0

相关博文

我的热门文章

img
取 消
img