麒麟子

~~

导航

<2010年4月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

统计

常用链接

留言簿(12)

随笔分类

随笔档案

Friends

WebSites

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜

[原]译:一个游戏引擎所应具有的元素

原文:http://www.flipcode.com/archives/Elements_Of_A_Game_Engine.shtml
Introduction (简介)

现在我们来说说你将如何写出一个支持华丽特性的3D引擎。你的引擎需要提供的包括:曲面(curved surfaces)、动态光(dynamic lighting)、体积雾(volumetric fog)、镜面(mirrors)、入口(portals)、天空盒(skyboxes)、顶点Shader(vertex shaders)、粒子系统(particle systems)、静态网格模型(static mesh models)、动画网格模型(animated mesh models)。如果你对上面这些都很熟悉了,你也许急着把这些东西整合到引擎当中。9 h: z( V0 G* m) m6 Z0 i p% a

但是请稍等!在你开始写代码前,你必须先思考一下你将用你的引擎来做什么。通常情况下,你应该想拿来做游戏,但如果你马上就开始写你的引擎,你会死得很惨,到后期你可能会因为要增加新的特效和控制重复编写大量的部分代码,最后很有可能以失败而告终。所以事先思考一下你的引擎设计,会为你节省大量时间和麻烦。你也不要一开始就指望建立一个大的工程,这样你可能也会力不从心,最后不了了之。其实这是一个学习所有东西的办法,从小从起,因为人无完人,所以,你最好是能完成你的项目,那样你会感到很自豪。

 

工具/数据

在开发的时候,你可能会需要一些数据,但不幸的是,如果用txt文件来定义一个立方体,是一件非常不容易的事情。所以,至少你得要一个3D建模软件(3d model editors),关卡编辑器( level editors)和图形程序(graphics programs)。这些东西都可以买到,但你也可以在网上找一些免费的。但更不幸的是,你有可能会需要更多网上没有的工具,所以,就需要你自已写了。如果你在网上找不到你想要的关卡编辑器时,你就需要自已写一个了。你还需要写一些代码来打包你的文件。因为要面对成百上千的文件是一件痛苦的事情。你还需要写转换器或是插件来将你3D建模软件导出的文件格式转换成你自已的。你还需要一些其它工具来处理你的游戏数据,比如能见度分析,光照贴图等。: j; O1 }1 }3 |) _2 K. L

有一个基本规律,那就是有可能你写工具的时间,可能比和写游戏花同样多的时间,或者说更多。前期你可以找你想要的工具和文件格式来用,但是总有一天你会意识到,对于你的引擎来说那些东西太普通了,于是你会意无反顾地写你自已的专用版本。

 

虽然使用现成的东西已经成习惯,但你应该注重你的代码质量。因为也许有一天有人想要使用,扩展或是修改你的工具。特别是如果你将要把你的引擎发布成开源,或是可以让人随意修改的时候,你更应该注意。( j3 R. T+ `' w9 _8 o
% x# Z) ^  K+ g
有可能你会花时间去做图形,关卡,声音,音乐和模型,工作量也和你写游戏,工具,引擎差不多。

 

系统是你的引擎和机器交互的部分,如果一个引擎写得非常好的话,那么将它从一个平台移殖到另一个平台,应该只会改动与系统相关的部分。系统包含了许多子系统,其中包括图形,输入,声音,定时器和配置。主系统负责初始化,更新和关闭这些子系统。( z v+ W4 v3 K; q$ v" B

图形子系统:它是一个非常直观的子系统,它就负责把东西显示到屏幕上。许多人都采有OPENGL,D3D,Glide或是软渲染等图形API来实现。但如果做得更好的话,你应该实现多种图形API的接口并在它们上面设置一个图形层,这样用户可以有多种选择,也提高了性能和兼容性。这个东西会有一点难度,特别是因为不是所有的图形API都拥有同样的结构。。。

输入子系统:它将获取所有的输入(Keyboard, Mouse, Gamepad and Joystick)并统一进行相应的控制。例如:在游戏逻辑中,用户希望向前移动他的位置。比起逐个检测输入类型并处理来讲,更好的做法是调用子系统,由子系统完成透明的设备检测过程。用户与玩家可以非常自由地切换输入装置,这样玩家就可以很容易地通过不同的输入装置来获取同一行为。

声音子系统:它负责载入、播放声音。该子系统功能非常简洁明了,但当前很多游戏都支持3D声音,实现起来会稍许复杂一些。1 e9 Z  F8 @8 C. R% m7 Q% T

3D 游戏引擎中很多出色的表现都是基于“时间系统”的。因此你需要一段时间来好好构思一下这个系统。即使它非常的简单,(游戏里)基本上所有东西都是通过时间触发来做移动变化,所以,如果你设计得比较好的话,就可以少写很多冗余代码。4 ~3 j  l" z/ I- ^# c

配置系统:位于所有子系统的顶端。它负责读取配置文件,命令行参数, 或是实现修改设置(setup)。在系统初始化以及运行期间,所有子系统都将一直与它保持通讯。比如:切换图象分辩率(resolution),色深 (color depth),绑定按键(key bindings),声音支持选项(sound support options),载入游戏等。这个系统将这些实现显得格外的简单和方便。如果你的引擎支持配置系统,那这调试和测试就方便多了,玩家与 用户也可以方便地选择他(她)们喜欢的运行方式。

控制台
我知道所有人都乐意去跟风做一个象Quake那样的控制台系统。但这的确是一个非常好的想法。通过命令行变量与函数,你就能够在运行时改变你的游戏或是引擎的设置,而不需要重启。开发期间输出调试信息也非常的有效。很多时间你都需要测试一系列变量的值,将这些值输出到控制台上要比 运行一个debugger速度显然要快得多。你的引擎在运行期间,一旦发现了一个错误,你不必立即退出程序。通过控制台,你可以做些非常灵活的控制,并将 这个错误信息打印出来。假如你不希望你的最终用户看见或是使用该控制台,你可以非常方便地将其隐藏,有人看得见就奇怪了。  ^2 l @8 H, d3 }: A

支持系统% `9 w1 m3 q; Q; F# ^. p' Z, U
   这个系统在你引擎中到处都在用。它包含了你引擎中所有的数学成分(点,面,矩阵等),(内)存储管理器,文件载入器,数据容器(假如你不愿自己写,也可以使用STL)。该模块任务针对于基础和底层,你也可以将它复用到其它相关项目中去。

渲染器/引擎内核
( ~是的,每个人都喜欢渲染3D图形。但是渲染一个3D世界有太多不同方法,那想要描述清楚所有图形管线工作的情况实在是太难了。

 

所以,暂时不管你如何实现渲染器吧,最重要的事情是让你的渲染器组件建立起来,并保持清析的结构。确保你的模块界线分明(不要把这个模块的放到哪个模块了,要放对哦)。我试着将渲染器拆分为以下几个部份:可见性(Visibility)、碰撞检测与反馈 (Collision Detection and Response)、摄像机(Camera)、静态模型(Static Geometry)、动态模型(Dynamic Geometry)、粒子系统(Particle Systems)、公告板(Billboarding)、网格(Meshes)、天空盒(Skybox)、光线(Lighting)、雾 (Fogging)、顶点SHADER(Vertex Shading)和输出(Output)。( Z6 z" n( o4 E5 g ]
) e4 \6 Y$ E, X2 }
所有的这些子模块都需要一个接口,用来更改它的设置,位置,朝向以及其它的一些与系统相关的设置

 

设计这个子系统的时候,主要克服的困难就是防止特性膨胀,因此,你应该在设计期间决定你想要实现什么样的特性。如果到最后你发现你不得不新增加特性的话,那说明你先前的设计很烂。

一个好而方便的事情就是你将所有的三角面最终提交给渲染管线中同样的点。(不是同一时间一个三角形,我是说三角形构成的方式 lists, fans, strips等等)多花一些时间让所有物体的具有同一格式,这样它们就都能使用相同的光照计算、雾、以及填充代码。但是到最后你会很高兴,因为这样你就能非常便利地仅通过切换材质与纹理id就使任何多边形具有不同的渲染效果。" h1 t6 g9 P3 J w

这不会对具有多种点的物体绘制造成影响,但是一旦你不当心,它可能会导致大量的冗余代码。7 n# [ b4 I, S4 u1 I. n3 V
/ A# m) a# H2 a: M" T* Q1 l# G
你最后会发现,当你实现所有这些NB的效果后,你的工作才做了15%或更少。这是就对了,图形效果在一个游戏引擎中的比重不大。

 

游戏接口- Z9 E4 `, b9 u+ ^
1 X) P W; E* _2 q' j5 f
一个3D游戏引擎最重要的就是它是一个游戏引擎,不是游戏。具体的游戏中的组件将不会被放到游戏引擎中去。在游戏引擎与游戏之间有一些薄薄的层(接口)。这样能够保持引擎的结构清析,也能让引擎能够便于使用。这是一些额外的代码,但是它使游戏引擎能够被复用并且可以使用脚本语言轻松地控制游戏逻辑,或者把游戏代码放到一个库中。如果你嵌入你的游戏逻辑到你的引擎中,那你以后想复用的时候,就不要幻想可以直接用了。

 

我想到现在你最迷惑的应该就是介于游戏和引擎之间的那层接口提供了些什么。答案是:控制。引擎的任何部分都有一些动态属性,因此,游戏/引擎层便是用来修改这些属性的一组相关接口。这些属性包括了摄相机,模型属性,光源,粒子系统,物理,播放声音,播放音乐,处理输入,更改关卡,碰撞检测和反应,移动一个2D图片到头上显示,屏幕标记等等。基本上,如果你想要你的游戏能够做这些事情,你的引擎就需要提供一个接口来让游戏逻辑使用。

  b
游戏% y7 l+ E+ b4 K2 I* L
6 [6 L# f" }! K; F
这里,我无法告诉你如何去写你的游戏。这该轮到你了。如果你已经为你那令人赞异的引擎设计出了一套出色的接口的话,我想你在编写游戏过程中一定会少很多麻烦。9 s W2 D: b3 v3 f. b) f
: p+ A4 S3 W- ]
3D游戏引擎设计是一项巨大的软件工程。一个人也能写出一个游戏,但这不只是熬一两个晚上便能搞定的,你很可能会出写出几兆的源代码量。如果你没有持久的信念与激情,你早晚会放弃。4 y4 g# c. p7 ~$ h1 P+ R+ v
5 S6 q, Z; \! _; `1 o$ I
当然,别指望你的第一次尝试就能写出完整的引擎,选择一个对引擎需求较小的项目。努力,你就能成功。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wqjqepr/archive/2010/04/26/5531974.aspx

posted on 2010-04-26 23:34 麒麟子 阅读(2138) 评论(11)  编辑 收藏 引用 所属分类: Game and Engine

评论

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 02:15 陈梓瀚(vczh)

以后就写在word里,然后复制到两个地方就好了。就不会出现这个问题了。如果下次还这样那说不定是因为你想宣传csdn专栏……  回复  更多评论   

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 08:27 小时候可靓了

我试了一下,复制到WORD里还不是要去删那些符号。。
另外,也是想宣传一下那个博客!!!  回复  更多评论   

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 09:35 zuhd

我只想说楼主你很ass hole,你要是想备忘,拜托不要发到首页好吗!你转到csdn的那些东西只会浪费大家的时间  回复  更多评论   

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 10:13 小时候可靓了

@zuhd
OK  回复  更多评论   

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 10:14 小时候可靓了

@zuhd
其实,你已经超越这个了,并不代表所有人都是。
有许多人需要看的!  回复  更多评论   

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 10:19 空明流转

@小时候可靓了
你根本就没明白你回复的那个哥们儿的意思,谢谢。  回复  更多评论   

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 11:00 小时候可靓了

@空明流转
好嘛,以后我不在这写了便是!  回复  更多评论   

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 12:39 Bill Hsu

全文贴过来就是了,
csdn速度巨慢  回复  更多评论   

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 12:58 幻想搭积木

最近频繁在CPP博客的订阅里看到你的博文嘛  回复  更多评论   

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 13:19 小时候可靓了

我用WORD写的都贴了的。。 但我从一些网站上复制我先前发的文章,就会乱码!!!  回复  更多评论   

# re: [原]译:一个游戏引擎所应具有的元素 2010-04-27 14:22 ccsdu2009

@幻想搭积木
呵呵我也是啊  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理