通信工程毕业设计(论文)-基于DirectX的第一人称射击游戏制作.doc_第1页
通信工程毕业设计(论文)-基于DirectX的第一人称射击游戏制作.doc_第2页
通信工程毕业设计(论文)-基于DirectX的第一人称射击游戏制作.doc_第3页
通信工程毕业设计(论文)-基于DirectX的第一人称射击游戏制作.doc_第4页
通信工程毕业设计(论文)-基于DirectX的第一人称射击游戏制作.doc_第5页
已阅读5页,还剩89页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

北京邮电大学世纪学院北京邮电大学世纪学院 毕业设计毕业设计( (论文论文) ) 题 目 基于基于 DirectX 的第一人称射击游戏制作的第一人称射击游戏制作 学 号 000 学生姓名 专业名称 通信工程 所在系(院) 通信与信息工程 指导教师 2012 年 6 月 1 日 北京邮电大学世纪学院毕业设计(论文)任务书北京邮电大学世纪学院毕业设计(论文)任务书 姓名学号通信工程系(院)通信与信息工程 设计(论文)题目基于 DirectX 的第一人称射击游戏制作 题目分类 工程设计; 工程技术研究; 软件工程(如 CAI 课题等); 专题研究;艺术设 计; 其他 题目来源 自然科学基金与部、省、市级以上科研课题; 企、事业单位委托课题; 院级课题; 自拟课题 其他 指导教师(指导教师 组组长及成员姓名) 职 称工作单位备注 讲师北邮信通院指导老师 毕业设计(论文)的内容和要求: 注意:选题尽量与实际应用需求相结合。要求写明本设计(论文)所涉及的分析方法或技 术手段(如定性、定量分析的方法) ;要求有学生独立的见解,设计内容要详细写明具体步 骤和技术指标。 开发一个简单的第一人称射击游戏: 1 游戏规划,包括角色模型,菜单界面等; 2 创建和使用纹理和光照,增加对硬件光照和纹理的支持; 3 在程序中增加对脚本和 GUI 的支持; 4 用边界框和边界球为游戏加入碰撞检测; 5 通过 Direct input 为游戏引擎加入输入检测功能,检测来自键盘,鼠标等设备 的输入; 6 使用 DirectSound 和 DirectMucic 播放声音,创建 3D 摄像机系统。 应完成的工作和提交材料要求(课题完成后应提交成果的种类、数量、质量等方面的要求): 开题报告:3000 字左右; 论文的中文摘要:200-300 字左右,包含关键词,并译成英文。 英文摘要以 250 个左右实词为宜; 论文正文不少于 15000 字; 可执行文件及源代码; 尽量结合课题,翻译 1500 汉字以上的有关技术资料或专业文献; 参考文献中,主要的文献应达到 10 篇以上,其中外文文献在 2 篇以上。 主要参考文献(参考文献不少于 4 篇,参考文献目录按 GB/T77142005 的要求填写): 1 左鲁梅.三维图形引擎中的关键技术研究D.北京:北京理工大学,2009 : 2130 2 孙家广.计算机图形学M.清华大学出版社.2008 : 5070 3 王鸽鸽.三维引擎的研究与实现D. 辽宁:东北大学.2008 : 2050 4 房晓溪. 游戏引擎教程M.中国水利水电出版社, 2008 : 3040 5 叶至军. Visual C+/DirectX9 3D 游戏开发导引 DirectX9 game programming tutorials. M.人民邮电出版社, 2006 : 5060 6 陈卡. DirectX 9 3D 图形程序设计M.上海科学技术出版社, 2003 : 2555 7 Allen Sherrod. DirectX 游戏开发终极指南 Ultimate game programming with DirectXM.清华大学出版社, 2008 : 5667 8 拉莫泽. 3D 游戏编程大师技巧M.人民邮电出版社, 2005 : 7780 9 David M. Bourg / 射线类 class CPlane; / 平面类 class CPolygon; / 多边形类 #includeRay.h #includePlane.h #includePolygon.h #includeMathDefines.h #endif 4.2.1 向量 如前所述,向量是3D游戏开发中涉及的最基本对象。3D向量保存在3D空间中指 定位置的3个轴上。这些轴分别是x轴、y轴和z轴,分别代表空间中的宽度、高度和 北京邮电大学世纪学院毕业设计(论文) 26 深度。这些值可对3D环境中的任意物体定位。3D向量是一个包含三个浮点数的结构。 3D数学库中有关向量的部分在引擎GameEngine项目中文件Vector.h与Vector.cpp中 定义和实现。在这两个文件中除了定义了向量在VC+中结构体的表示方法外,还包 括向量长度、点积、叉积、向量归一化的计算,以及Direct3D向量的定义和各种数 学运算。为其它部分调用向量计算提供基础。 4.2.2 矩阵 在计算机图形学中,诸如矩阵这样的对象可以控制物体的位置和旋转。矩阵是 浮点数的2D数组,可以对矢量进行平移、旋转、缩放和变换。从根本上讲,矩阵是 由行和列构成的表。矩阵有多种形式,如33、34和44。这里矩阵的数分别代 表2D数组包含的行数和列数。例如,44矩阵由16个元素组成,因为44矩阵有4 行,4列(44=16)。3D数学库中有关矩阵的部分在引擎GameEngine项目中文件 Matrix.h与Matrix.cpp中定义和实现。在这两个文件中除了定义了矩阵的在VC+中 的表示方法外,还包括44矩阵的乘法、转置和旋转计算,以及Direct3D矩阵内置 对象和函数的初始化。 4.2.3 四元组 旋转是3D编程中最常用的操作之一。旋转用于改变物体方向,或是绕着场景中 某个轴或具体的点转动,并且可以移动骨骼动画中要用到的骨架点。正因为旋转如 此重要,所以提高它们的精确度、速度和效率具有很重要的意义。例如,就骨骼动 画而言,存储效率和速度对系统也许是最重要的两个要素,这是由系统的复杂性和 存储旋转数据所需的内存就决定的。 曾有一段时间使用矩阵实现旋转,出现过问题。这主要是因为使用矩阵会消耗 大量内存和运算时间,甚至在某些时候会产生Gimble lock问题而无法准确计算旋 转结果。而四元组是4D数学对象,并不是4D矢量,但能当作4D矢量对待。它充分解 决了使用矩阵转换的缺点。用四元组计算会得到更平滑的计算结果,更准确的旋转, 而不会受到Gimble lock的影响。 3D数学库中有关四元组的部分在引擎GameEngine项目中文件Quaternion.h与 Quaternion.cpp中定义和实现。在这两个文件中除了定义了四元组在VC+中结构体 的表示方法外,还包括四元组点积、长度、乘法等的计算。 北京邮电大学世纪学院毕业设计(论文) 27 4.2.4 射线 射线是包含原点(位置)和方向的结构。射线主要在查看两个平面是否发生碰撞, 或相互之间可能会出现碰撞时做碰撞检测使用。同样,可以通过鼠标使用射线来选 择对象。计算机图形学中射线的另一种用途是实现一种名为射线跟踪的渲染技术。 简单地讲,射线跟踪是在场景中发射射线,并确定哪一根射线击中了哪一个物体。 3D数学库中有关射线的部分在引擎GameEngine项目中文件Ray.h与Ray.cpp中定 义和实现。在这两个文件中定义了射线在VC+中结构体的表示方法。 4.2.5 平面 平面是一个无限扩展的区域。是3D场景中的核心部分,如果没有平面,将无法 进行诸如几何图形选择和碰撞检测等操作。 3D数学库中有关平面的部分在引擎GameEngine项目中文件Plane.h与Plane.cpp 中定义和实现。在这两个文件中定义了平面在VC+中结构体的表示方法以及计算三 角形法线,判断平面与平面、平面与射线间是否相交,点与平面的关系,点与平面 的距离等计算的实现。同时,它们也实现了Direct3D平面的初始化操作。 4.2.6 三角形和多边形 Direct3D应用程序中的一些图元由诸如多边形这样的对象构成。多边形是封闭 的平面图形,边界由一些线段组成。多边形是一个面,由三个或更多的相连成形的 点构成。读者可以见到,最常用的一类多边形是三角形。三角形由三个互连在一起 组成像2D金字塔形状的不同点构成。 3D数学库中有关三角形和多边形的部分在引擎GameEngine项目中文件 Polygon.h与Polygon.h.cpp中定义和实现。在这两个文件中定义了三角形和多边形 在VC+中结构体的表示方法。 4.3 DirectX3D 光照 光照是一门为3D场景增加真实感的技术,它以某种方式通过对物体分布不同的 亮光和黑暗形成阴影而实现真实感。如同在现在许多游戏中见到的一样,光照可以 将场景带入到一个全新的真实感层次。为场景增加光照会对已渲染的场景产生巨大 的影响。图4.3给出了相同场景的三个不同光照的版本。左边的场景没有光照和阴 影,中间的场景有光照而没有阴影,右边的场景两者都有。 北京邮电大学世纪学院毕业设计(论文) 28 图 4.3 相同场景的三个不同光照版本 4.3.1 光源 光源是 3D 场景中发光的物体。这种所谓的光会导致阴影发生不同的变化,因 而产生更具有真实感和更令人感兴趣的场景。通过在场景中基于“光”信息让物体 从亮到黑逐渐发生变化,可以在图形程序中创建非常真实的光照模拟。然后增加阴 影,只是在看不见光源的表面上出现亮度变化,如黑色或是黑灰色。换句话说,有 另一个表面介于光源和要增加阴影的表面之间。 通常在计算机图形学中有三类光源需要考虑,分别是点光源、聚光光源和方向 性光源。 (一)点光源 点光源是一种在某个距离上向所有方向发光的光源。随着光传播一定的距离, 它会损失一定的能量而且亮度也会逐渐降低。 (二)聚光光源 聚光光源在一定距离上散法能量(类似于点光源)。与点光源的差别在于聚光光 源是通过一个圆锥将光发射到 3D 场景中,而不是在各个方向都发光。 (三)方向性光源 在计算机图形学中,第三种光被称为方向光。这些光像是从某个方向发生出来 的,而没有特定的光源(整理者:类似于太阳光)。现实生活中,所有的光源都有一 个产生光的源点,但在计算机图形学中产生一种没有发光源点的光源也是可能的。 在光照计算机过程中,通过几个数学计算就可以实现该光源。这些光源看上去不是 很真实,但它们在渲染简单的场景和简单形状的演示程序时,却足以满足要求。 北京邮电大学世纪学院毕业设计(论文) 29 4.3.2 反射模型 反射模型描述了光照射到某个表面时,入射光在物体表面上的作用方式。当一 些光被反射回场景中时,一部分光能被存储。这些表面也就是所谓的材料。材料只 是一些属性,描述了材料被照射时做出的满应方式。更改这些属性将得到不同的效 果。计算机图形学中有许多不同的反射模型,但最常用的模型分别是环境光反射模 型、漫反射模型和镜面反射模型。反射模型和光属性一起确定了 3D 场景中物体的 外观。 (一)环境光反射 环境光反射描述的是场景中没有方向的光,但是可以从各个地方都可以看到。 因为从每个表面将光反射回来,这样就很难辨认光的原始位置。环境光试着模拟全 局照明,这是场景中光从场景表面反射回来多次之后形成的光总量。当光从表面上 反射离开的时候,它沿着一定的方向反射。这些光线中的一部分进入到观察者的眼 睛中,这样就可以看到周围的环境。 (二)漫反射 漫反射模型描述了光线从表面上在各个方向做相同反射的方式。这意味着如果 看一个只由漫反射光照的物体,那么从各个角度看上去该物体都是相同的。漫反射 是视觉独立的,只有物体移动或是光移动时,才会发生变化。当光线照射在散射表 面时,它会在多个方向反射。物体越光滑,反射光线散射得越光滑。除了物体的阴 影区域外,物体从各个角度看上去都一样。 (三)镜面反射 镜面反射模型模拟了从光滑发光表面如镜子、一块金属或一块发光塑料等发射 光线的情况。表面的镜面属性就是在光线中看到的大部分物体上发亮的光。如果移 动一个发光物体,就会注意到镜面亮光区所发生的变化。这意味着镜面反射取决于 观察物体的角度。所以漫反射光与视觉无关,而镜面反射光与视觉相关。 4.3.3 在 DirectX3D 中创建光照与材质模型 为了在 Direct3D 中创建光源,必须创建一个 D3DLIGHT 对象。为了方便起见, 下面程序设置了光照结构。不必设置所有的属性值,而属性值的设置取决于创建的 光源类型。 typedef struct _D3DLIGHT9 北京邮电大学世纪学院毕业设计(论文) 30 D3DLIGHTTYPE Type; / 定义了所要创建的光源类型 D3DCOLORVALUE Diffuse; / 该光源所发出的漫射光的颜色 D3DCOLORVALUE Specular; / 该光源所发出的镜面光的颜色 D3DCOLORVALUE Ambient; / 该光源所发出的环境光的颜色 D3DVECTOR Position; / 用于描述光源在世界坐标系中位置的向 量。 D3DVECTOR Direction; / 一个描述光在世界坐标系中传播方向的 向量。 float Range; / 光线“消亡”前,所能达到的最大光程。 float Falloff; / 仅用于聚光灯。定义了光强从内锥形到 外锥形的衰减方式 float Attenuation0; / 该衰减变量定义了光强随距离衰减的方 式。仅用于点光源和聚光灯 float Attenuation1; / 同 Attenuation0 float Attenuation2; / 同 Attenuation0 float Theta; / 仅用于聚光灯。指定了内部锥形的圆锥 角,单位为弧度 float Phi; / 仅用于聚光灯。指定了外部锥形的圆锥 角,单位为弧度 D3DLIGHT9; 同样,在 DirectX3D 中定义的材质结构体如下: typedef struct D3DMATERIAL9 D3DCOLORVALUE Diffuse; / 指定表面反射的漫反射光 D3DCOLORVALUE Ambient; / 指定表面反射的环境光 D3DCOLORVALUE Specular; / 指定表面反射的镜面光 D3DCOLORVALUE Emissive; / 表面本身自发光 float Power; / 镜面高光 北京邮电大学世纪学院毕业设计(论文) 31 D3DMATERIAL9, *LPD3DMATERIAL9; 4.3.4 引擎中增加对光照的支持 项目一开始先创建名为light.h、material.h的两个文件。light.h头文件用于 创建灯源结构,该结构用于创建Direct3D中的灯源对象。以某种方式实现该结构, 这样也可将其用于OpenGL或其他渲染系统。material.h与光源结构非常相似,因为 它可同时用于为Direct3D和OpenGL创建材质数据。材质结构包含了创建不同类型材 质所必须的全部信息。 在引擎渲染接口文件RenderInterface.h与定义实现文件D3DRenderer.h和 D3DRenderer.cpp中添加对光源材质设置的声明与定义,以及启动光源函数。如下: / 设置并启用光源 void CD3DRenderer:SetLight(stLight *light, int index) if(!light | !m_Device | index ambientA; l.Ambient.r = light-ambientR; l.Ambient.g = light-ambientG; l.Ambient.b = light-ambientB; l.Attenuation0 = light-attenuation0; l.Attenuation1 = light-attenuation1; l.Attenuation2 = light-attenuation2; l.Diffuse.a = light-diffuseA; l.Diffuse.r = light-diffuseR; l.Diffuse.g = light-diffuseG; l.Diffuse.b = light-diffuseB; 北京邮电大学世纪学院毕业设计(论文) 32 l.Direction.x = light-dirX; l.Direction.y = light-dirY; l.Direction.z = light-dirZ; l.Falloff = light-falloff; l.Phi = light-phi; l.Position.x = light-posX; l.Position.y = light-posY; l.Position.z = light-posZ; l.Range = light-range; l.Specular.a = light-specularA; l.Specular.r = light-specularR; l.Specular.g = light-specularG; l.Specular.b = light-specularB; l.Theta = light-theta; if(light-type = LIGHT_POINT) l.Type = D3DLIGHT_POINT; else if (light-type = LIGHT_SPOT) l.Type = D3DLIGHT_SPOT; else l.Type = D3DLIGHT_DIRECTIONAL; m_Device-SetLight(index, m_Device-LightEnable(index, TRUE); 4.4 DirectX3D 纹理 开发令人信任的背景和环境是3D游戏项目的核心所在。场景中的几乎每个表面 都会应该人一种很强的视觉效果和触模感。砖墙是由砖块构成的,木板箱是由许多 块木板构成的,还有诸如此类等等。针对当前这种办法,产生的问题就是为了获取 表面上更好的细节层次,就需要上千万的独立的着色小三角形,这样,创建游戏场 景耗费的时间就无法估计,没有什么经济价值,并且还要占用大量的处理器资源。 解决上述问题需要一种更好的增加细节层次的方法,并且不会增加不必要的代 码或是对象和场景的复杂度。“纹理映射”技术可以实现这样的效果。纹理映射使 北京邮电大学世纪学院毕业设计(论文) 33 用了图像数据并将图像数据绘制(映射)到表面上。该表面看上去就像有一幅图在它 上面。所以,如果有一堵墙,并将砖块的纹理施加到这堵墙上面,那么即便只是这 个表面使用了两个三角形,它看上去也像场景中的一堵墙。如图4.4中的示例。 图 4.4 纹理贴图示例 4.4.1 创建使用纹理 在Direct3D中加载图像时要用到一个名为LPDIRECT3DTEXTURE9的结构。 LPDIRECT3DTEXTURE9结构是Direct3D中的纹理对象,在加载1D或2D纹理图像时要用 到该结构。无论何时创建LPDIRECT3DTEXTURE9纹理对象,都要调用对象的Release()函 数对其进行释放。下列程序代码列举了D3DXCreateTexture()的原型: HRESULT WINAPI D3DXCreateTexture( LPDIRECT3DDEVICE9 pDevice, / Direct3D9的设备对象 UINT Width, / 图像宽度 UINT Height, / 图像高度 UINT MipLevels, / 图片的图层,一般用D3DX_DEFAULT,与图像质量 有关 北京邮电大学世纪学院毕业设计(论文) 34 DWORD Usage, /设定这个纹理的使用方法 D3DFORMAT Format, / 每个颜色成分使用的位数 D3DPOOL Pool, / 纹理对象驻留的内存类别 LPDIRECT3DTEXTURE9 * ppTexture / 指向新创建的纹理对象 ); 4.4.2 引擎中增加对纹理的支持 引擎中添加纹理要做的第一件事情就是增加启用和禁用透明度渲染状态、设置 透明度渲染状态值并指明滤波器和滤波器类型的功能。这些可以在 defines.h 头文 件中完成,如下列程序所示。新添加的代码位于 defines.h 头文件的尾部。 / 一些渲染状态 enum RenderState CULL_NONE, CULL_CW, CULL_CCW, DEPTH_NONE, DEPTH_READONLY, DEPTH_READWRITE, SHADE_POINTS, SHADE_SOLIDTRI, SHADE_WIRETRI, SHADE_WIREPOLY, TRANSPARENCY_NONE, / 禁用透明度 TRANSPARENCY_ENABLE / 启用透明度 ; / 透明度渲染状态值 enum TransState TRANS_ZERO = 1, 北京邮电大学世纪学院毕业设计(论文) 35 TRANS_ONE, TRANS_SRCCOLOR, TRANS_INVSRCCOLOR, TRANS_SRCALPHA, TRANS_INVSRCALPHA, TRANS_DSTALPHA, TRANS_INVDSTALPHA, TRANS_DSTCOLOR, TRANS_INVDSTCOLOR, TRANS_SRCALPHASAT, TRANS_BOTHSRCALPHA, TRANS_INVBOTHSRCALPHA, TRANS_BLENDFACTOR, TRANS_INVBLENDFACTOR ; / 纹理过滤器的过滤模式 enum TextureState MIN_FILTER, / 缩小率 MAG_FILTER, / 放大率 MIP_FILTER / mipmap 纹理级别 ; / 纹理过滤器类型 enum FilterType POINT_TYPE, / 最近点采样 LINEAR_TYPE, / 线性纹理过滤 ANISOTROPIC_TYPE / 各向异性纹理过滤 北京邮电大学世纪学院毕业设计(论文) 36 ; 下一步是在引擎渲染接口文件RenderInterface.h与定义实现文件D3DRenderer.h 和D3DRenderer.cpp中添加对纹理设置的声明与定义,以及纹理读取、透明度,幕 外渲染等各种函数。代码略。 4.5 DirectX3D 文本和图形用户界面 4.5.1 DirectX3D 文本 为了在一个基本层次上显示文本,要用到两个不同的对象,即LPD3DXFONT和 RECT这两个结构。LPD3DXFONT用于创建和显示文本,而RECT用于确定要显示的文本 位置。为了创建LPD3DXFONT对象,就要用到一个名为D3DXCreateFont()的函数。该 函数原型如下列程序清单所示。其成员变量如下: HRESULT D3DXCreateFont( LPDIRECT3DDEVICE9 pDevice, INT Height, / 字体字符的高度 UINT Width, / 字体字符的宽度 UINT Weight, / 打印字体的权重(即:粗体) UINT MipLevels, / 文本的Mipmap级别 BOOL Italic, / 字体是否为斜体 DWORD CharSet, / 用到的字符集 DWORD OutputPrecision, / 指定Windows与期望字体大小的匹配方法 DWORD Quality, / 指定Windows将字体和真实字体的匹配方法 DWORD PitchAndFamily, / 斜度和family索引 LPCTSTR pFacename, / 要用的字体类型名称 LPD3DXFONT * ppFont / 要填充的LPD3DXFONT对象 ); 渲染文本对象就要用到LPD3DXFONT对象的DrawText()函数。即在屏幕上显示指 定的文本。程序的原形如下: INT DrawText( LPD3DXSPRITE pSprite, / 指向包含字符串的LPD3DXSPRITE对象的指针 北京邮电大学世纪学院毕业设计(论文) 37 LPCTSTR pString, / 屏幕上要显示的文本 INT Count, / 字符串字符的数目 LPRECT pRect, / 一个RECT对象,定义了要显示在屏幕上的第 一个字符的起始位置 DWORD Format, / 指定字符串的显示方式 D3DCOLOR Color / 屏幕上显示的文本颜色 ); 4.5.2 创建和显示图形用户界面 用户图形界面(GUI)系统将主要由按钮和静态文本控件对象构成。同时,可 以指定和按钮、文本一起显示的背景图。 GUI 系统包括含有纹理坐标的 GUI 顶点结构、GUI 控件结构和 GUI 系统类。GUI 顶点结构包括(x,y,z)点的坐标;GUI 控件结构包括控件类型、ID、颜色、索引链表 等信息;GUI 系统类包括添加设备、背景图像 GUI、返回高度长度等函数。除此之 外,还要有一个系统回调函数,来响应控件动作。这些功能定义在 GUI.h 中,代码 如下: / GUI 控件结构 struct stGUIControl int m_type; / 控件类型 int m_id; / 控件 ID unsigned long m_color; / 控件颜色 int m_listID; / 链表索引,字体对象 ID 或顶点缓存 ID int m_xPos, m_yPos; / 控件的 XY 坐标 int m_width, m_height; / 控件的宽和高 char *m_text; / 指向静态控件文本字符的指针 北京邮电大学世纪学院毕业设计(论文) 38 int m_upTex, m_downTex, m_overTex; / 按钮的弹起、按下和停靠 ; / GUI 控件系统类 class CGUISystem public: / 构造函数 CGUISystem() : m_controls(0), m_totalControls(0), m_backDropID(-1) / 析构函数 CGUISystem() Shutdown(); int IncreaseControls(); / 添加背景图控件 bool AddBackdrop(int texID, int staticID); / 添加静态文本控件 bool AddStaticText(int id, char *text, int x, int y, unsigned long color, int fontID); / 添加按钮控件 bool AddButton(int id, int x, int y, int width,int height, 北京邮电大学世纪学院毕业设计(论文) 39 int upID, int overID,int downID,unsigned int staticID); / 内存清理 void Shutdown(); / 获取指定 ID 的 GUI 控件对象 stGUIControl *GetGUIControl(int id) if (id = m_totalControls) return NULL; return / 返回控件对象总数 m_totalControls int GetTotalControls() return m_totalControls; / 返回指定背景图控件对象 stGUIControl *GetBackDrop() if (m_backDropID = 0 / 失败则返回 0 值 北京邮电大学世纪学院毕业设计(论文) 40 return NULL; private: stGUIControl *m_controls; / GUI 控件对象指针 int m_totalControls; / 控件对象的数量 int m_backDropID; / 背景图控件的 ID ; 4.5.3 引擎中增加对文本和 GUI 的支持 引擎文件中添加了很多代码,这样可以显示文本和 GUI。defines.h 头文件为 GUI 提供了许多新的 define(定义)语句。下列程序给出了 defines.h 头文件中新添 加的代码。 / 用于确定 GUI 元素在屏幕上的位置 #define PERCENT_OF(a, b) (int)(a * b) / GUI 控件矩形的灵活顶点格式 #define GUI_FVF 2 / GUI 控件类型 #define UGP_GUI_STATICTEXT 1 / 静态文本控件 #define UGP_GUI_BUTTON 2 / 按钮控件 #define UGP_GUI_BACKDROP 3 / 背景图控件 / 鼠标的状态 #define UGP_BUTTON_UP 1 / 左键在按钮上弹起 #define UGP_BUTTON_OVER 2 / 停靠在按钮上 #define UGP_BUTTON_DOWN 3 / 左键在按钮上按下 北京邮电大学世纪学院毕业设计(论文) 41 对于 GUI,引擎中主要提供对 GUI.h 文件中各个函数的实现。代码略。另外, 还要更新 RenderInterface.h、D3DRenderer.h 和 D3DRenderer.cpp 文件。这样可 以扩充 GUI 系统,这些类中新添加的函数有 CreateGUI()、AddGUIBackdrop()、 AddGUIStaticText()、AddGUIButton()和 ProcessGUI()。新增变量有 m_guiList(GUI 界面链表)和 m_totalGUIs(确定系统中要显示的 GUI 界面数量)。定 义代码如下: class CD3DRenderer : public CRenderInterface public: / .The original class functions. / 添加背景图 GUI bool AddGUIBackdrop(int guiId, char *fileName); / 添加静态文本 GUI bool AddGUIStaticText(int guiId, int id, char *text, int x, int y, unsigned long color, int fontID); / 添加按钮 GUI bool AddGUIButton(int guiId, int id, int x, int y, char *up, char *over, char *down); / 绘制 GUI void ProcessGUI(int guiID, bool LMBDown, int mouseX,int mouseY, void(*funcPtr)(int id, int state); / .The rest of the classs functions. 北京邮电大学世纪学院毕业设计(论文) 42 4.6 DirectX3D 特效 3D游戏最值得关注的主题之一就是它的视觉效果。特效用于表现自然世界或虚 拟世界中的图形学现象。这包括爆炸、雪、雨、雾、光照效果、动态模糊、反射等。 就像在电影行业中一样,特效可以增强屏幕内容。在实时和非实时仿真中可以实现 很多效果。正确的特效有助于增强用户更深层的体验。这里将介绍几种可运用到 Direct3D场景中增强场景真实感的不同技术。同时还将介绍使用多采样降低渲染物 体,基于顶点的雾,细节纹理映射和一个简单的雨粒子系统。 4.6.1 多采样 全景抗混叠是一种减少在渲染多边形的边时所产生的参差不齐效果的方法。抗 混叠物体也会对渲染后的整个场景产生负面影响,尤其是处理动画更是如此。通过 实现对像素的本地模糊处理,并在屏幕上显示出一个平均结果而实现全景抗混叠。 图 4.5(左)是抗混叠物体, (右)为场景渲染后的物体。 图 4.5 多采样示例图 在Direct3D中启用多采样将实现程序中的抗混叠。多采样将对程序性能的影响 很大。采样数越高,渲染的场景质量就越好。样本最大数取决于支持它的硬件。在 Direct3D 9.0中,多采样类型包含了 D3DMULTISAMPLE_NONE、D3DMULTISAMPLE_NONMASKABLE、D3DMULTISAMPLE_2_SAMPLE S以及D3DMULTISAMPLE_16_SAMPLES。默认情况下使用D3DMULTISAMPLE_NONE,这意 味着并不使用任何类型的多采样。使用D3DMULTISAMPLE_2_SAMPLES和 D3DMULTISAMPLE_16_SAMPLES或它们之间任意其他采样都会让Direct3D知道在对场 北京邮电大学世纪学院毕业设计(论文) 43 景多采样时使用的样本数。 4.6.2 雾 为 3D 场景增加雾会得到更真实的渲染效果。雾可以增加大量真实感,尤其对 地形、树林地区以及幽灵般的户外背景。同样,雾可以很好地限制观察者对环境的 可见度。现实中并不存在无限的视觉距离。事实上,这就是虚拟环境的一个镜像。 Direct3D 中有两类硬件雾可用:顶点雾和像素雾。顶点雾是按照每个顶点来计 算雾的数据,而像素雾根据像素级别计算雾的数据。由于通常像素比顶点要多得多, 因此两者相比而言,像素雾的渲染速度较慢。同样,顶点雾提供了很好的视觉效果。 有了顶点雾,就可以在表面上逐点内插处理雾的信息。 图 4.6 是采用雾特效的一个截图: 图 4.6 雾特效截图 4.6.3 粒子系统 粒子系统保存和操纵一种称为粒子的元素。粒子系统的职责就是对粒子施加不 同的作用力,为它们增加一种真实的外观。粒子系统的类型包括爆炸、烟、火、火 北京邮电大学世纪学院毕业设计(论文) 44 花等,而其他类型的效果可由许多小的元素构成。粒子是一个小物体,包含多种属 性,如位置、速度(方向)和质量。 相关粒子特效的程序内容保存在文件 RainPS.h 和 RainPS.cpp 中。图 4.7 是 “粒子雨”特效: 图 4.7 粒子特效截图 4.6.4 引擎中增加对特效的支持 为了在引擎中支持特效,首先在defines.h文件中为想要在引擎中使用的雾和 多采样功能添加几个define语句。对雾而言,将使用想要创建的雾的枚举类型。对 多采样而言,将使用可以支持的多采样枚举类型。对该引擎而言,这里将支持非多 采样、2倍、4倍、8倍和16倍速率采样等几种采样类型。雾枚举类型的名称是 UGP_FOG_TYPE,而多采样枚举类型的名称是UGP_MS_TYPE。在define.h文件中添加 的代码如下: / Multi-sampling. enum UGP_MS_TYPE UGP_MS_NONE, 北京邮电大学世纪学院毕业设计(论文) 45 UGP_MS_SAMPLES_2, UGP_MS_SAMPLES_4, UGP_MS_SAMPLES_8, UGP_MS_SAMPLES_16 ; / Fog. enum UGP_FOG_TYPE UGP_VERTEX_FOG, UGP_PIXEL_FOG ; 然后需要在引擎渲染接口文件RenderInterface.h与定义实现文件D3DRenderer.h 和D3DRenderer.cpp中添加对特效的设置的声明与定义,以及特效多采样、雾和粒 子系统等各种函数。代码略。 4.7 基本脚本系统 通过在程序中编写脚本的方法,允许用户和程序员以脚本的内容来控制系统的 行为。脚本是一个包含了大量告诉程序工作方式的指令文件(文本或二进制)。可以 在不需要重新编译程序的情况下,通过更改脚本文件来改变程序的行为。通过在文 件中放置指令,程序员可以打开文件、读取脚本,按照脚本中的内容执行所要执行 的工作。一些有名的脚本系统包括(Game Monkey脚本、Java脚本、Unreal脚本、 LUA和Python)。在游戏中使用脚本就增加了让用户修改程序的可能性。 4.7.1 属性脚本系统 属性脚本只需定义属性及其值即可。从另一个角度理解,属性脚本就是定义了 变量及其值的脚本文件。基本上,属性脚本系统都必须读取文本文件中的每个属性 及其后面的值。对它而言,为了这样做,那就必须指定像分隔符这样内容。 属性脚本系统包含PropertyScript.h头文件、PropertyScript.cpp源文件。在 PropertyScript.h头文件。在该文件中定义了一个枚举变量,以枚举这里将要支持 北京邮电大学世纪学院毕业设计(论文) 46 的不同类型的属性,一个定义矢量对象(3个分量)的结构,一个名为CVariable的属 性类以及属性脚本系统自身。CVariable类用于存储单个属性,在其中定义了属性 名、属性类型以及一个支持每种类型的成员变量。 属性脚本系统CPropertyScript包含3个成员变量:一列CVariable对象、列表 中的属性总数、跟踪正在读取的当前字符的计数器。最后一个成员变量只有读取文 件时才用到,这样可以在解析文件时确定位置。一旦读取完文件,最后一个成员变 量就没有用了。 由于属性可以是4种不同类型之一,因此同样需要有成员函数返回每种类型。 这在CVariable和CPropertyScript两个类中都可以实现。需要有一种方法能够确定 属性类型,这样才能返回正确的成员变量。下列程序清单给出了完整的 PropertyScript.h头文件。 / 枚举了一些类型 enum enVarType NULL_VAR = 0, INT_VAR, FLOAT_VAR, STRING_VAR, VECTOR_VAR ; / 存储3D向量类型的结构 struct stVector stVector() : x(0), y(0), z(0) float x, y, z; ; / 用于描述单个属性(文本)的类 class CVariable public: CVariable() : type(0), floatVal(0), intVal(0), stringVal(0) name0 = 0; vecVal.x = vecVal.y = vecVal.z = 0; 北京邮电大学世纪学院毕业设计(论文) 47 CVariable() if(stringVal) delete stringVal; stringVal = NULL; / 用新的变量名替换旧的变量名,然后调用重载函数,完成数据的设置 void SetData(int t, char* n, void *data); / 设置数据 void SetData(int t, void *data); / 获取属性名 char *GetName() return name; / 获取属性值的类型 int GetType() return type; / 获取int类型的属性值 int GetDataAsInt() return intVal; / 获取float类型的属性值 float GetDataAsFloat() return floatVal; / 获取string类型的属性值 char *GetDataAsString() return stringVal; / 获取stVector类型的属性值 stVector GetDataAsVector() return vecVal; 北京邮电大学世纪学院毕业设计(论文) 48 private: char name128; / 属性名 int type; / 属性类型 / 对应类型的属性值 int intVal; float floatVal; char *stringVal; stVector vecVal; ; / 总的属性脚本系统类 class CPropertyScript public: CPropertyScript(); CPropertyScript(); bool IncreaseVariableList(); bool LoadScriptFile(char *filename); private: / 获取当前所读取的一行中某个单独文本,并保存在第2个参数中 void ParseNext(char *tempLine, char *varName); public: bool AddVariable(char *name, int t, void *val); bool SetVariable(char *name, int t, void *val); int GetVariableAsInt(char *name); 北京邮电大学世纪学院毕业设计(论文) 49 float GetVariableAsFloat(char *name); char *GetVariableAsString(char *name); stVector GetVariableAsVector(char *name); void Shutdown(); private: CVariable *variableList; / CVariable对象链表,用于保存各个 属性名及属性值 int m_totalVars; / 列表中

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论