游戏开发基础:游戏开发基础(3)



第 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符号定义

Tags:  网页游戏开发 网络游戏开发 游戏开发 游戏开发基础

延伸阅读

最新评论

发表评论