2 mesh->Release() //释放mesh3 好了,编译运行。。。如果不出意外的话,你肯定看不到茶壶,而是一条黑线为什么呢?再漂亮的美女,站在你背后,你也欣赏不到美,计算机就更笨了,你得告诉它看什么,向哪里看,这就需要设置设置view matrix和projection matrix,现在来设置它们,定义一个函数SetupMatrix,如下Code并在OnD3D9FrameRender函数中调用之1 SetupMatrix(pd3dDevice) // 调用自定义的SetupMatrix函数
2 3 // Render the scene4 if( SUCCEEDED( pd3dDevice->BeginScene() ) )5 {6 mesh->DrawSubset(0)
7 V( pd3dDevice->EndScene() )8 }9 好了,再次编译并运行,哇,茶壶出现了!可是仍然是黑色的,黑的不好看,来个彩色的吧,OK,继续!要想使Model丰富多彩,就要设置材质(material)和光照,这两个属性决定了Model的最终颜色,简单解释一下这两个属性,和现实生活中的情况是一样的。同一束光照在不同的材质上效果是不同的,比如一束光在石头上和照在玻璃上效果肯定不一样。所以材质是决定光照的一个因素,也就是光的反射程度,映射到D3D中就是设置材质的漫射光属性。另一个就是关照本身了,在这里我们使用平行光。于是添加如下函数设置光照效果。diffuse表示漫射光,而ambient表示环境光,一般将他们的值设为相同r,g,b分别表示红,绿,蓝三种颜色的程度,范围是0.0-1.0,在这里r和g设置为1.0而b设置为0.0,实际上构造了一个反射黄色光的材质,也就是我们最终看见的model颜色将是黄色。再将入射光定为白色,方向指向x轴正向。一般来说,D3D程序通常将入射光设置为白色,而通过设置材质来决定最终的反射光颜色,本例即如此。Code在OnD3D9FrameRender函数中调用之1 SetupMatrix(pd3dDevice)
2 SetupLight(pd3dDevice)
3 再次编译运行,哇,经典的蓝黄配!但是这个茶壶是固定的,如何让它动起来呢,使之可以响应用户的输入。这就需要用到DXUT的Camera类,这里我们使用ModelViewCamera来实现,默认情况下,生成的EmptyProject是不包含Camera类的,所以我们要手动添加,来到程序所在目录,将DXUT-Optional文件夹下的DXUTres.h,DXUTres.cpp,DXUTcamera.h和DXUTcamera.cpp四个文件加入到工程中的DXUT文件夹下在EmptyProject.cpp文件头部加上下面一句,以便可以使用camera类1 #include "DXUTCamera.h"定义一个全局变量保存model camera1 CModelViewerCamera modelCamera 在OnD3D9CreateDevice函数中设置view matrixeyePt 眼睛 位于z轴的负半轴5个单位距离处,DirectX使用左手系,z轴正向指向屏幕内部。lookAt 视点 位于坐标原点通过这个设置,我们相当于在z轴负半轴5个单位距离处朝坐标原点看至于向上向量,camera类会为我们设置,一般是 D3DXVECTOR3 up(0.0f, 1.0f, 0.0f)1 D3DXVECTOR3 eyePt(0.0f, 0.0f, -5.0f)
2 D3DXVECTOR3 lookAt(0.0f, 0.0f, 0.0f)
3 modelCamera.SetViewParams(&eyePt, &lookAt)
4 在OnD3D9ResetDevice函数中设置投影矩阵Code注意,到这里时,上面那个自定义的SetupMatrix函数就可以不用了,因为我们使用Camera来处理矩阵了在OnFrameMove函数中调用camera的FrameMove函数1 modelCamera.FrameMove(fElapsedTime)在MsgProc函数中调用camera的消息处理函数,这使得model camera可以处理鼠标消息1 modelCamera.HandleMessages(hWnd, uMsg, wParam, lParam) 最后,也是最重要的,是OnD3D9FrameRender函数中的代码在每一帧开始绘制之前,我们要取得当前的矩阵并应用到当前的Scene中Code好了,运行程序看看,貌似和前一次没什么区别啊?区别大了!现在你可以:拖动鼠标左键旋转model,注意旋转model时光照效果不变拖动鼠标右键旋转camera,注意旋转camera时光照会发生明暗变化,因为我们的视点变了,这就好比一束光照向茶壶的正面,茶壶不动,光的方向也不改变,而你作为观察者围着茶壶转,当你转到茶壶背面时,你将看到比较暗的一面。滑动鼠标滚轮,向前滑动时,是zoom in,茶壶会被放大,向后滑动时,是zoom out,茶壶会被缩小。
关卡设计的工具是什么?是引擎。这个答案简单明了。每个熟悉3D游戏的玩家,都会把Unreal、Doom3、Source这样的引擎挂在嘴边。不过,引擎到底是什么?
我就以Unreal为例,解释一下引擎的构成与基本功能。
所谓的“Unreal引擎”,实际上指的是“Unreal Editor”这个编辑器。游戏公司花钱买引擎,实际上就是买这一套基本编辑器的使用权与修改权,同时享受引擎开发公司的技术支持。这个编辑器是一个集成的编程环境,可以理解为3D MAX的部分功能加上一个集成化的C编程环境——虽然看起来很复杂,但是只要掌握了用法就会觉得很方便。这个编辑器也是程序组和设计组两组人马的区别所在,程序员们面对的是编辑器以下的底层工作,而设计师们要面对的则是在编辑器基础以上的设计工作。例如在我们UBI,程序员们基本上是与游戏内容无涉的。
和如今绝大多数的3D引擎一样,Unreal引擎的基本设计概念是基于BSP(Binary Space Partition,可以翻译作二进制空间区块)上面的。简单来说,一个BSP就是空间中的一个基本单位,例如一个立方体就是一个BSP。一个BSP可以是空心的,也可以是实心的;Unreal引擎的默认设定是整个空间都是实心的,然后用空心的BSP在实心空间中“挖”出可利用空间来。BSP的最大特点就是“简单”,为了绘图和计算方便,搭建BSP的时候都要使用尽可能简单的形状和结构。这是由于BSP本身全部都需要即时演算生成,如果结构复杂的话,有很多复杂相切的话,系统计算量会很大。
对于比较复杂的物件,比如场景、摆设、人物等等,就不能使用BSP即时演算了,需要预先做好3D物体与贴图,放在内存中再由引擎读入。这种物件我们称作Mesh。Mesh有两种:动态Mesh和静态Mesh。动态Mesh(Animation Mesh)要和动画搭配,一般都是用来表现人物角色,这个部分由动画组负责制作;静态Mesh(Static Mesh)就是那些没有必要做出动画的普通Mesh,一个游戏中绝大多数的摆设、物件都是这一类。Mesh按照种类分别在引擎中打好包,关卡设计师可以随时调用;如果关卡设计中需要什么特殊的物品,一般也会让美工打包加入其中。倘若是有特殊功能的物品,比如和主角或敌人有互动的Mesh,程序员还会给它们加上调用接口。但Mesh和BSP有一个相当大的不同:为了优化起见,一般Mesh都不会做碰撞计算(由于形状比较复杂的缘故)。如果是要做碰撞计算的物体,一般还要单独加上一层碰撞Mesh(Collsion Mesh)。碰撞Mesh基本上都比普通Mesh结构简单,而且不用贴图。
当然,有很多游戏需要野外场景,有些还需要大量的野外场景,比如“幽灵行动”系列。在这种情况下,引擎提供了功能强大的地形编辑功能(Terrain Editor)。和BSP不同,Terrain并不是方块,而可以完成比较复杂的地形结构,但相对地消耗资源也比较厉害。因为一个Terrain需要很多的贴图层和多边形来绘制,而且几乎总不能隐藏。所以,在大多数游戏中,你很难见到地形复杂的室外场景——至于背景远处的远景,一般都是用消隐面加上背景盒(Skybox)来完成。
编辑器中和关卡设计相关的另外一个重要功能是放置Actor。Unreal中所有的东西都被列属于Actor类之中,包括BSP和Mesh,但除去这两类之外还有很多其他的Actor,这些Actor往往和游戏内容相关。例如,NPC的移动需要有路点或者引导Mesh;NPC的自动掩护和行动,需要有Coverspot、Actionspot之类的东西;NPC的AI需要有Script Actor;和玩家相关的重要位置,需要有判定点和目标点;游戏中的特殊音乐和音效,需要有声音Actor……在某些游戏(比如强调黑暗行进的分裂细胞)中,灯光也和关卡设计有很大关系。这些具体的内容要视游戏而定,但摆放的好坏却决定了一个关卡设计的优劣。关于摆放和AI,我会在下面专门谈到。
根据具体游戏的不同,引擎还有许多其它的功能,不过那都是细节问题。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)