Issuu on Google+

游戏开发基础:游戏开发基础(3) 疯狂代码 http://CrazyCoder.cn/

ĵ:http:/CrazyCoder.cn/GameDevelopment/Article35910.html

第 3章 DirectX SDK介绍 第节 有关DirectX SDK Microsoft DirectX提供了套非常优秀应用接口包含了设计高性能、实时应用源代码DirectX技术将帮助您建构 下代电脑游戏和多媒体应用它内容包括了DirectDraw、DirectSound、DirectPlay、Direct3D和DirectInput等 部分它们分别主要应用在图形、声音等方面 由于DirectX使在Windows下运行应用性能可以和在DOS或游戏平台下运行应用性能相媲美甚至超过它们它将 为您Windows游戏开发提供个具有鲁棒性、标准化操作环境 DirectX包括两部分:运行期部分(Runtime)和SDK在DirectX开发时这两部分都要用到但在DirectX应用运行时只 用运行期部分在Windows NT 4.0及以上版本中含有DirectX运行期部分Win95则没有但Win95可以很容易获得 DirectX运行期部分而Windows NT 4.0以前版本不能运行DirectX许多基于DirectX应用和游戏都包含了 DirectX运行期部分 它目前有 5个版本:1、2、3、5和6(没有版本4)区别版本具有区别运行期部分但新版本运行期部分可和旧版本应 用配合即向上兼容当前大部分流行游戏都是基于版本5开发

第 2节 DirectX5 SDK获得 DirectX SDK包括开发DirectX应用所需要到全部举例和帮助文件但这些都是可 选资源必须文件是头文件(.h文件)和库文件(.lib文件)获得DirectX SDK比获得运行期部分要困难些Windows NT 4.0和Win95都不带DirectX SDK,要获得SDK可通过以下3种办法: * 购买Visual c5.0(包括DirectX SDK) * 访问Microsoft Web站点DirectX下载页 * 成为MSDN(Microsoft开发网络)用户 SDK 也可以从Microsoft Web站点上获得,下载量很大,尤其是在拨号连接时,有可能需要整夜时间 成为MSDN用户是获取SDK好办法除非您反对通过Microsoft付费方式获得升级及其操作系统开发特权SDK由 MSDN level 2及以上提供

第 3节 元件对象模型(COM) DirectX根据MicrosoftCOM(Component Object Model即元件对象模型)规格得以实现COM设计成用来提供 完全便携、安全、可升级软件Software结构COM使用个面向对象模型这要比像C等语言所用模型更严格例如 COM对象经常通过成员进行存取而且并不具备公共数据成员COM对继承性支持和C相比也是有限 很多DirectX中API是作为COM对象例子来创建您可以这样看:对象就象个黑盒子它代表了硬件从而需要通过个 接口和应用进行联络通过COM接口发送和接收命令被称为“方式(method)”例如方式


IDirectDraw2::GetDisplayMode是通过接口IDirectDraw2发送从而能够从DirectDraw对象得到当前显示适配 器显示模式 COM对象提供实际性而COM接口则提供存取性思路方法COM对象不能被直接存取相反所有存取者通过接口来 完成这条规则是如此强有力得到遵守以致于我们不能给任何COM对象以名称我们只能给用来存取对象接口名称 所有COM接口都是从IUnknown接口中衍生出来“I”标志经常用于命名COM接口(它代表Interface即接口) IUnknown接口提供3个成员所有COM接口因而继承这些: ●AddRef:使对象内部引用值加例如当您创建个新接口时构造将自动AddRef ●QueryInterface:让COM对象就它们是否支持特定接口进行查询例如升级COM对象提供附加接口而非现有接 口修改版QueryInterface可以用来确定旧接口以决定新接口是否被支持如果被查询对象不支持有问题接口则更 替接口指针就返回 ●Release:使对象内部引用值减您应该在接口指针将要超出范围时或者要通过使用接口指针来结束时使用这个 对象每个DirectX接口都代表了种设备例如IDirectDraw2、IDirectSound和IDirectPlayDirectX对象模型象征性 地为每个设备提供了个主对象其它所支持功能对象由主对象衍生而来例如DirectDraw对象代表了显示适配器您 可以由它创建DirectDrawSurface对象来代表显存同样地DirectSound对象代表声卡并可以创建 DirectSoundBuffer对象代表声卡上声音资料 在C中可以任意COM接口方式下面例子创建个平面使用DirectDraw对象IDirectDraw2::CreateSurface方式: ret = lpDD->lpVtbl->CreateSurface (lpDD, &ddsd, &lpDDS, NULL); 这里lpDD表示和新建平面相关DirectDraw对象该方式填充个平面类型结构(&ddsd)并返回个指向平面指针 (&lpDDS) 同样功能用C实现为: ret = lpDD->CreateSurface(&ddsd, &lpDDS, NULL)

第 4节 DirectDraw DirectDraw是DirectX SDK中个组件它允许用户直接地操作显存支持硬件覆盖、内存和显存反转DirectDraw在 提供这些功能同时并支持基于Microsoft Windows应用和设备驱动DirectDraw作为种软件Software接口支持 WindowsGDI(图像设备接口)并提供直接操作显示设备功能它提供了和设备无关游戏、Windows子系统等软件 Software开发方式 它还能够支持许多种显示硬件包括从简单SVGA显示器到高级硬件性能(支持图像剪切、延伸和非RGB颜色格式 )接口设计使您应用能够知道所使用硬件特性从而可以支持它们硬件加速功能 有关DirectDraw在以后还将有更加详细讲解

第 5节 DirectSound Microsoft DirectSoundAPI是DirectX平台软件Software开发工具(SDK)员指南声音组件DirectSound提供了硬


件加速、对声音设备直接操作在提供这些功能同时它还保持了和当前设备驱动兼容性 新版本DirectSound能够在运行中查询硬件性能以确定最优操作方式还具有抓获声音、低延迟混音等功能特性 它新功能还包括支持属性集(Porperty Sets)从而即使DirectSound不直接支持新硬件特性它也能够利用并受益 DirectSound是通过“硬件抽象层(HAL)”来操作声音硬件这是个由声音设备驱动来实现接口HAL提供了以下功 能: 要求和释放对声音硬件控制; 描述声音硬件特性; 在硬件允许条件下实现特定操作; 在硬件不允许时候报告操作失败 DirectSound能够自动地利用硬件加速包括硬件混音和硬件声音缓冲您应用无须查询硬件和特性而可以在运行 期部分查询DirectSound来获得对声音设备特性充分描述然后根据各个特性存在或缺少来使用区别思路方法进 行优化您还可以指定接受硬件加速声音缓冲区 下图显示了DirectSound和系统中其它声音组件关系:

有关DirectSound在以后还将有更加详细讲解

第 6节 DirectPlay DirectPlay主要作用在于使应用间通讯方式得以简单化DirectPlay技术不仅提供了个方案实现了通讯和传送协议 及在线服务无关性而且还实现了和传输服务器和游戏服务器无关性万所基于网络不支持某方式DirectPlay包含 了必要代码来仿效它 DirectPlayservice provider结构使应用和网络隔绝开来应用通过查询DirectPlay来获得所基于网络功能特性(例 如延迟、带宽等)从而相应地调整通讯方式下面图显示了DirectPlay service provider结构: 使用DirectPlay第步是选择使用哪种service provider它决定了将用于通讯网络或协议协议可以是遍布 InternetTCP/IP、局域网中IPX或两台计算机间连接电缆 DirectPlay提供了两种很有用连接管理方式: IDirectPlay3::EnumConnections列举了应用可以获得所有连接; IDirectPlay3::InitializeConnection化种特定连接 在确定了网络连接后为了方便理解下面内容先来看看这样几个概念: 首先从session讲起DirectPlay session是若干台计算机的间通讯通道个应用只有在成为了某个session部分后才 能够开始和其它计算机进行通讯有两种思路方法可以实现:列举个网络中所有存在session然后加入其中个;或 新建个session并等待其它计算机加入当应用成为session部分后它就可以创建个player并和session中其它 player相互传递信息


每个session中都有台计算机作为主机主机是session所有者并拥有唯改动session属性权力 下图显示了个session模型: Session有两种类型:对等类型和客户/服务器类型 Player是session中逻辑概念上对象能够发送和接收消息在DirectPlay Session中没有对实体计算机表示思路方 法Player可以作为个本地player(在您自己计算机上)或作为个远程player(在其它计算机上)只有在拥有了至少个 player后计算机才能够发送和接收消息每台计算机可以拥有不止个本地player Group是在逻辑概念上是些player集合通过创建个group个应用可以向它发送消息使其中所有player都收到 DirectPlay提供了管理group和成员关系方式 下图显示了个session内容逻辑结构: 假如台计算机在完成了连接的后就可以IDirectPlay3::EnumSessions列举所有可以得到session然后 IDirectPlay3::Open根据session cache中内容加入个session或新建个session 接下来可以创建player和group而在游戏中更多是通过Message Managment中各个方式进行频繁地、大量消 息传送 在区别类型session中消息流向是区别在对等类型中消息传送是各个player的间直接进行对于使用multicast向 group中传送消息时则要在group中指定个multicast server通过它再将消息传送给group中其它计算机 在客户/服务器类型session中所有player只和服务器进行直接通讯再由它和其它各个客户机进行消息传送下图 表示了这样关系:

第 7节 DirectInput DirectInput用以支持包括鼠标、键盘和游戏杆等在内输入设备甚至还有力度反馈高级输入/输出设备它也是基 于COM DirectInput对象由输入设备提供数据每个相应设备都有所谓“对象例子”即个别Control控件如按键、按纽和 游戏杆轴向等键盘上每个按键都可以作为键盘对象个对象例子即使在后台运行DirectInput也能够对输入设备做 出响应 般来说先要创建个DirectInput对象(通过DirectInputCreat方式)表示个DirectInput子系统然后列举出系统中可 以得到输入设备再为这些个别设备创建DirectInputDevice对象(通过IDirectInput::CreateDevice方式)这种对象 方式用于获取有关设备信息设置它们属性并从它们那里得到数据 下面给出个使用鼠标例子您可以在光盘Example目录下Scrawl.c文件中找到这些代码 首先创建DirectInput鼠标设备 // LPDIRECTINPUT g_pdi; // 已被化 LPDIRECTINPUTDEVICE g_pMouse; HRESULT hr;


hr = g_pdi->CreateDevice(GUID_SysMouse, &g_pMouse, NULL); (FAILED(hr)) { Complain(hwnd, hr, \"CreateDevice(SysMouse)\"); FALSE; } CreateDevice方式有 3个参数:第个是全局独有标志符GUID_SysMouse这里表明为鼠标;第 2个是 IDirectInputDevice接口指针类型如果这个成功它就指向可用鼠标;般不使用COM聚合体第 3个参数为NULL 然后设置鼠标信息格式: hr = g_pMouse->SetDataFormat(&c_dfDIMouse); (FAILED(hr)) { Complain(hwnd, hr, \"SetDataFormat(SysMouse, dfDIMouse)\"); FALSE; } 设置鼠标行为: hr = g_pMouse->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND); //后面两个标志符实现了前台运行时对输入设备独占 (FAILED(hr)) { Complain(hwnd, hr, \"SetCooperativeLevel(SysMouse)\"); FALSE; } 要使用事件通告(event notication)来发觉鼠标动作并将经过缓冲鼠标输入读进来这都需要进行些设置首先创建 个事件将它和鼠标联系起来当发生硬件中断时就可以告诉鼠标设备对象有新数据来到 // HANDLE g_hevtMouse; // 全局变量 g_hevtMouse = CreateEvent(0, 0, 0, 0); (g_hevtMouse NULL) {


Complain(hwnd, GetLastError, \"CreateEvent\"); FALSE; }

hr = g_pMouse->SetEventNotication(g_hevtMouse); (FAILED(hr)) { Complain(hwnd, hr, \"SetEventNotication(SysMouse)\"); FALSE; } 现在您需要设定缓冲区大小在此的前要化个DIPROPDWORD结构这当中很多数量是无关紧要关键是最后个 dwData它决定了缓冲区中可容纳项目数量 # DINPUT_BUFFERSIZE 16 DIPROPDWORD dipdw = { // the header { (DIPROPDWORD), // diph.dwSize (DIPROPHEADER), // diph.dwHeaderSize 0, // diph.dwObj DIPH_DEVICE, // diph.dwHow }, // the data DINPUT_BUFFERSIZE, // dwData }; 接着按照您希望改变属性标志符将头地址传送给IDirectInputDevice::SetProperty方式: hr = g_pMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph); (FAILED(hr)) {


Complain(hwnd, hr, \"Set buffer size(SysMouse)\"); FALSE; } 至此设置结束然后开始根据要求操作鼠标 第 8节 Direct3D Direct3D提供了和硬件无关3D视频硬件操作方式您可以在两种模式(立即模式和保留模式)中选择其中的使用 立即模式较保留模式是个低层3D API后者建构于前者的上立即模式适合于开发高品质多媒体应用它在底层和加 速硬件进行通讯保留模式应用于对3D场景进行实时操纵 对3D场景操作是基于矩阵和多边形运算这是创建和管理3D基础知识在很多资料中均可获得 使用立即模式可以选择通过DrawPrimitive方式或利用执行缓冲区对于初学者般从DrawPrimitive方式不过千万 不要认为两者有优劣的分在熟悉了Direct3D后使用哪个思路方法取决于您应用要求前者思路方法和其它COM雷 同;在利用执行缓冲区思路方法时要创建DirectDraw和Direct3D对象设置渲染状态填充执行缓冲区等 无论哪种模式应用和硬件通讯都很类似正如下图所示由于Direct3D相当于DirectDraw对象个接口这里HAL被表 示为DirectDraw/Direct3D HAL 对保留模式操作是通过使用些对象来实现Direct3D和DirectDraw是紧密联系在起个DirectDraw对象将 DirectDraw和Direct3D状态封装起来通过IDirectDraw::QueryInterface方式将IDirect3D接口转换为 DirectDraw对象 有个很重要概念是z缓冲区它决定了将很多显示内容如何覆盖和裁剪如果没有z缓冲区保留模式无法给覆盖层排 序没有指定z顺序覆盖层被缺省设定为0处于最底层共可以有 4十亿个覆盖层(应该够用了吧!)z顺序为2层将可 能遮掩了z顺序为1层某些内容记住不能有两个层z顺序相同 有关3D场景还有诸如材资、光源等概念在此不再聱述 第 9节 Vc中引入Direct SDK 旦安装了SDK就得马上通知Visual C SDK位置默认状态下SDK安装在dxsdk目录下头文件放在dxsdk/inc目录下 库文件放在dxsdk/lib目录下 可利用下述两种思路方法的通知visual C SDK位置种思路方法是在使用文件时给出完整文件路径;另种法是将 这些目录加到Visual C搜索路径中第 2种思路方法更好些可以通过Tools[Options]Directories对话框实现 增加dxsdk/lib目录思路方法大体上同增加dxsdk/inc目录思路方法相同 如果你获得了个含有比Visual CDirectX SDK新版本您需要将DirectX SDK目录置于常规Visual C目录上面否则 就得使用旧版本(Visual C从上至下查找目录)


根据我们已经讨论过内容你应该能够编辑DirectX了然而还有最后个潜在障碍除非INITGUID符号已经被定义否 则在DirectX GUIDs下Query-Interface同DirectX2 SDK链接会失败INITGUID符号只能由个源文件定义并且必 须出现在#语句的前如下列代码所示: # INITGUID #〈ddraw.h〉 //…other s…    对于DirectX3及以上版本这种解决思路方法都是有效但还有个更好思路方法即将dxguid.lib文件链接到你工程 上(Build[Settings]Link对话框)以替代INITGUID符号定义 2009-2-12 5:16:38 疯狂代码 http://CrazyCoder.cn/


3D游戏开发基础