3D游戏引擎设计与实现1-15

来源:互联网 发布:免费产品推广软件 编辑:程序博客网 时间:2024/05/16 10:10

 /***********************************
 *作者:蔡军生
 *出处:http://blog.csdn.net/caimouse/
 ************************************/
 
 3D游戏引擎设计与实现1-15
3D游戏引擎设计与实现(1)
       当写这个标题时,心里想:有可能实现出来吗?现在抱着学习与实践态度,只要去努力,肯定会有收获的。费话少说,下面就开始把自己的想法先写出来,因为有目的而来,从来不打没有准备的仗。
       在进行这个项目之前,肯定先去学习一下什么叫Computer graphics,就是计算机图像,它跟图像处理是大的不同,因为它是研究怎么样生成图像,而图像处理主要图像压缩存储等。除了这个之后,还要学习一点线性代数和空间解析几何。有这些基础之后,就可以去看看DirectX的例子,看看什么是3D,在计算机怎么样表示3D物体,当然要了解复杂的光照,还需要物理知识等。
       我设计这个3D游戏引擎,主要实现很简单的功能,细节的东西目前先不用考滤,因为开发过程是迭代的,不可能第一次就开发一个完美的引擎,也不可能一下子完成。先选择合适平台、开发工具和设计大体架构。这里我选择主要是Windows平台,并且3D的API就选择DirectX,目前不支持OpenGL。开发工具就用VS 2003.net中文版,因为它支持C++达到98%,这样可以完全使用C++的性能,面向对象的设计,模板方式重用代码。架构设计取用模块式设计,采用COM方式的DLL实现,这样可以把每个模块开发来,达到代码最大化的重用。
       现在总结一下目标是什么,如下:
l         平台:Windows平台
l         3D API: DirectX
l         开发工具:VS 2003.net中文版
l         架构:COM方式的DLL
还有很多东西没有想到,等着后面更进一步的设计。
 
 3D游戏引擎设计与实现(2)
3D游戏引擎设计与实现(2)
       经过几天萌思苦想,总算又设计3D游戏引擎的架构细节部份。原来说到要用到像COM组件的DLL实现,因此怎么样把游戏公共部份写到一起,变化部份写到一起,这样就能达到源程序重用,也可以简少维护工作。同时又把不同的功能模块尽量分开,把每个模块变成单一的功能,这样就可以复杂性降到最低了。
       目前大体分为:加载程序,DLL管理模块,引擎管理模块,UI模块,渲染模块,文件管理模块,游戏逻辑功能模块,游戏AI功能模块。以后想到的模块再添加也是可以的,因为都基于接口的方式实现,每个DLL都有自己的接口。
       下面来说明这些模块的作用:
l         加载程序
这个模块主要是实现游戏目录的重定位,或者一些其它的初始化工作。
l         DLL管理模块
这个模块主要实现所有DLL加载,创建对象,它就是所有DLL对象工厂,由它来创建所有对象,并且负责删除所有对象。
l         引擎管理模块
这个模块主要把其它各个模块组合在一起,并且进行游戏状态机更新和维护,还有消息处理,窗口维护,输入控制并把当前控制消息传给游戏逻辑模块。
l         UI模块
这个模块主要实现窗口的UI配置,比如创建新游戏,参数配置等。
l         渲染模块
这个主要在3D API之上实现更好用的Render功能,当然在这个模块里分成DX7,DX8,DX9等等的DLL,以便实现游戏可以在不同的平台上运行,这里的平台差别主要指显示卡的差别,因为不同的DX显示卡,使用不同的加速功能。有用户有钱就可以买最好的DX9显卡,没有多少钱的也许就是DX8的显卡。但总不能把游戏写成DX8的标准方式,因为买DX9显卡的用户肯定想:我花了那么多钱,还玩这破游戏。
l         文件管理模块
这个主要实现资源的加载和管理,比如基于MDL,或者DX的X文件格式。同时也可以进行游戏截图保存等等功能。
l         游戏逻辑功能模块
这个是不同的游戏产品,肯定不同的,比如基于FPS的游戏和RPG的游戏就不一样的游戏逻辑。因此这里主要进行游戏具体实现的功能,比如人物角色怎么样在地图里行走。
l         游戏AI功能模块
这个功能主要实现AI部份,比如寻路算法,NPC的控制。
目前,又想到这么多了,更多的东西还要更深入地去分析和设计,更加需要实践。
 

 3D游戏引擎设计与实现(3)
3D游戏引擎设计与实现(3)
       经过几天编写,3D游戏引擎的架构代码大体架构已经搭好。
       下面来每个模块说明:
l         加载程序
Engine/MM3DMain.exe
l         DLL管理模块
Engine/bin/MM3DRun.dll
l         引擎管理模块
Engine/bin/MM3DEngine.dll
l         UI模块
Engine/bin/MM3DGameUI.dll
l         渲染模块
Engine/bin/MM3DRender.dll
l         文件管理模块
Engine/bin/MM3DFileSystem.dll
l         游戏逻辑功能模块
Engine/bin/MM3DGame.dll
l         游戏AI功能模块
Engine/bin/MM3DGameAI.dll
上面就是每个模块的DLL,分别实现相应的功能和接口,所有DLL都是通过接口来实现对外功能。已经可以让程序运行起来,创建了基于窗口的模式。

 3D游戏引擎设计与实现(4)
已经把每个DLL的架构已经搞好,还把接口也定义了相应部份,目前这个程序已经可以运行,那么怎么样进行下一步设计呢?
我是先把所有消息循环写好,然后创建窗口,就基于写好主体程序,接着就要写相应DirectX初始化部份,就是要写MM3DRenderDX9.dll模块.
就是用它来封装所有DX接口,并提供给引擎管理模块使用,当然,还要给UI部份使用.
接着下来,就是实现UI部份DLL.它是通纹理来实现一个3D对话框.
好了,今天就写到这里,继续写代码.....................................


 3D游戏引擎设计与实现(5)
        今天终于实现了UI的显示,但还是比较初步的,已经可以显示按钮在窗口上,还没有添加事件响应,不过也会很快实现的.到此,基本上UI方面没有什么大的问题,还要解决输入法方面问题,因为在游戏中可能要输入中文,让所有游戏玩家可以相互聊天.
        接着下来,就是全部写UI部份,然后再写好窗口模式和全屏模式的相互转换,还要检查设备是否丢失等等.在写查找3D设备显示模式时的代码,还是非常的傍大.经过一个晚上不断地努力,总算实现出来了.
        到目前为止,这个3D引擎可以显示基于纹理的UI.还有很多东西在后面,还需要不断地努力.


 3D游戏引擎设计与实现(6)
今天又有一点进展,主要实现UI的消息处理。因为每个UI界面上的控件,比如按钮都自己实现消息处理。鼠标消息、键盘消息等等,非常之多。所以目前的工作主要在GameUI模块,目前实现的渐渐显示出来效果,还是不大好看,等以后有时间再重新考虑改进。

 3D游戏引擎设计与实现(7)
3D游戏引擎设计与实现(7)
       昨天在调试代码时,发现大量占用CPU资源,不知那里出什么问题,这个可以真是无从下手,正在苦恼时,突现发现,为什么不用帧速率来看看显示了多少帧。接着下来就添加帧速率上去,在调试时输出,发现每秒钟只有2到5帧,为什么会这么少的呢?又要从哪里下手去找出为什么这么慢的原因。只能用最笨的办法了,首先查看设备类型,因为它决定主要因素。接着去创建D3D设备的函数里调试,发现创建设备类型的参数是REF,就是使用标准设备,用软件模拟的,心里想:不慢才怪呢。所有东西都是用软件实现。原因肯定是在这里了,接着就跟踪为什么不能创建HAL类型的设备。最后找到了原因,就改正过来,结果显示到60多帧了。总算解决了一个问题。
       在调试窗口与全屏模式时,也经常出现调试程序和VC死锁问题,看来这种切换是不能单步调试,只能写LOG实现调试了。
   
 3D游戏引擎设计与实现(8)
3D游戏引擎设计与实现(8)
       昨天主要进行窗口模式切换到全屏模式的编写,这里的代码也非常的多,很多地方都要注意,很多细节都要处理,否则就可能程序死在那里,或者全屏模式时转换不到窗口模式,又或者当用户改变屏幕分辩率,这时如果没有改变窗口的模式的话,又会出现错误。还有一种情况,当切换失败时,又要尽量回退到原来显示参数的模式等等。这个功能实现,几乎就把DX的初始化功能基本上完成了。当然,当窗口改变大小,D3D的设备也要跟着改变。还要不断地调试才能完成这部份的功能。Coding................

 3D游戏引擎设计与实现(9)
 
       昨天还是进行窗口模式与全屏模式相互切换的代码工作,还有调试。不断地写LOG,不断跟踪,排除了一个又一个BUG后,总算可以自由地切换窗口模式与全屏模式。在这个过程中,不知道死了多少次VC,还好Windows2000的死进程管理能力还不错,还是没有要按下电源的键。当从全屏模式切换到窗口模式时,一定不要进行单步调试,否则就要死在那里。不过也没有办法,死几回还是需要的。这样慢慢地改进,就可以从全屏切换到窗口模式。
       这个功能总算实现了,后面接着又写当窗口改变大小的处理代码,因为所有的UI,在窗口方式中处理时,都跟窗口大小有关系。继续Coding..................

 3D游戏引擎设计与实现(10)
    经这几天的努力,已经把UI,D3D设备管理完成了,接着要开始写其它部份。要写哪部份才更好呢?我想肯定是先考虑怎么样渲染世界里所有的物品。要渲染物品得确定使用什么模型文件。现在可以选择的有好几种格式,第一种最方便的,应是用X的文件格式,因为D3D已经把它完全封装好。第二种是使用MDL文件格式,就是HL的格式。第三种就是QUAKE3使用MD3的格式。其实每种格式都有自己的优点和缺点,就看着自己喜欢用那种格式,看起来还是比较难选择的。
    经过不断地考虑,想试着使用MDL的文件格式。因为我没有美工,至少可以拿当前的CS的资源来实现一下,比较现实一点。   
    目前暂时不考虑加载的资源的内存管理方面,先实现加载模式文件作为第一步,然后再考虑怎么样显示这些物体在场境里。说到场境,主要分为两大类:室内和室外。每种场境都要分开来实现,室内场境比较好实现,因为就是在一个四方体的盒里,粘贴上不同的纹理来实现。室外的就比较麻烦,因为要有天空,树木,花草以及地表。
    今天身体不大舒服,有点发热,可能要过几天才写这个了。
 3D游戏引擎设计与实现(11)
3D游戏引擎设计与实现(11)
       已经到开始考虑怎么样去渲染场境,因为游戏里主要部份就是由场境组成,然后再添加各种人物在里面,因此就要思考怎么样保存场境,3D引擎怎么样加载它。现在为了用到CS的资源,当然要用它的地图文件,才可以更加方面。到目前,就决定使用BSP的地图文件格式,这种文件格式比较复杂,保存的数据也比较多。
       接着下来的,就是实现怎么样读取BSP文件格式,然后把它渲染到D3D设备里,所以要在MM3DFileSystem.dll里添加所读取BSP文件的代码。

 3D游戏引擎设计与实现(12)
3D游戏引擎设计与实现(12)
       游戏的地图文件格式是非常重要的一种格式,设计得好与坏,都关系到读写和渲染速度。如果保存的信息过少,就会导致渲染时花费大量的时间在计算。就目前主流的3D游戏,都会用这种思想:就是能预先计算的东西,就要先计好,不是在游戏中实现计算。比如用BSP树来保存冲突检测,保存可见性等,都是为了提高渲染速度。
       在CS的BSP文件格式中也是这样的,先计算好所有场境的BSP数据,这样就可以快速渲染。起先我还不知道什么叫BSP,就得赶紧去学习什么叫BSP。看看那本计算机图形学原理的书,原来只是用来保存面的可见性。BSP就是Binary Space Partition(ing)。这个文件里除了保存BSP树的数据外,还有使用到的纹理信息,模型信息等。
 3D游戏引擎设计与实现(13)
3D游戏引擎设计与实现(13)
       继续写读取地图文件格式的代码,因为这里保存了很多信息。又没有什么好文档,只好慢慢来找出BSP文件有用的信息,比如顶点,纹理坐标等。先读取显示场境里所有顶点数扰,平面方程数据,多边形的边数据,然后就可以构造自己的世界里的平面了。目前还没有加载纹理进来。Coding......


 3D游戏引擎设计与实现(14)
    今天没有写什么代码,主要看看地势生成算法。这个算法叫做Real-Time Optimal Adapting Mesh。它的思想就利用等边直角三角形可以无限分成两个等边直角三角形来表示地势的细节程度。如果要表示高细节的地表,就可以用分解成更多的直角三角形,如果表示不要求那么多的细节,着重于在速度,就可以分解三等边直角三角形少一点。
这个算法就称为ROAM算法。
 3D游戏引擎设计与实现(15)
    今天在写游戏逻辑部份的代码,主要实现游戏逻辑的实现,比如世界的场境是怎么样渲染,当然这些都是按照地图文件里定义,根据BSP树保存着的信息,就可以渲染场境出来.这样就可把需要的模型加载进来,每当玩家改变输入装态时,就会作出来不同的响应.比如行走系统,就是当玩家按下不同的方向时,就可以按着一定的速度向前移动,这里的移动,就是通过向量相加实现.当改变方向,就是绕着不同的轴进行旋转.
    同时,我在MM3DGame模块里加入渲染接口,让这里可以随便实现渲染.这里有很多问题要考滤,比如使用顶点缓冲区的方式,可以直接使用,或者使用顶点缓冲索引也可以.继续Coding.....

 

原创粉丝点击