游戏引擎的元素

Elements Of A Game Engine
游戏引擎的元素
● 作者 Luke Hodorowicz 译者 龚敏敏
Introduction 简介
So lets say your writing a 3D game engine that supports a pretty good set of features. Your list of desires includes curved surfaces, dynamic lighting, volumetric fog, mirrors and portals, skyboxes, vertex shaders, particle systems, static mesh models and animated mesh models. If you have a good idea of how all these things work, you can probably start putting these things together into an engine.

假如说你正在写一个能够支持一大堆很好的特性的3D游戏引擎。你列出了希望实现的东西,包括曲面、动态光照(dynamic lighting)、体积雾(volumetric fog)、镜面、入口(portals)、天空盒(skyboxes)、顶点光影(vertex shaders)、粒子系统、静态网格模型和动态网格模型等等。如果此时你已经很清楚地知道怎样去实现这些东西了以后,或许就该开始着手把这些东西一起塞进一个引擎了吧。

But wait! Before you start coding you need to think about what you're going to do with your engine. Most likely, you have aspirations of making a game. If you just jump in and start coding an engine, you're gonna get burned and end up having to re-write huge portions of the engine multiple times to add effects and control later. A little forethought into engine design will save headaches and time. The thing you don't want to do is aspire to huge projects. You'll end up not finishing it, and moving onto something else. While this is a way to learn everything you need, you won't be completing things. It's good to actually finish projects. You'll feel better for it and you can show off!

先等等!在你开始写代码以前,你必须先考虑清楚你打算用这个引擎来做什么。最常见的情况是,你渴望用它来做一个游戏。如果你仅仅是一头扎进引擎的代码堆里的话,你将会倍受煎熬,因为在以后当你要为游戏增加效果和控制时,你得反复重写引擎中的大部分代码。在这个时候,具备一点点对引擎设计方面的远见将为你省下不少时间,免去你头疼的烦恼。我们所不想遇到的是一个巨型的项目,因为我们可能会以失败告终,而转向别的课题。你想学会所有的东西,后果却一事无成。脚踏实地地完成一个项目才是正确的。只有这样,你才能感到愉悦,才能炫耀自己!

Let's take a look at the basic components of a full-featured 3D game engine. First off, this is for those people are reasonably experienced with 3d but need a little direction. These are not hard and fast rules that you must use. It's just what has worked well for me and to give an overview of how much work and how many parts go into a game engine. I call these parts System, Console, Support, Renderer/Engine Core, Game Interface, Game, and Tools/Data.

让我们审视一下一个具备完整特性的3D引擎应该包含那些基本组成部分。首先声明一下,本文是为那些已经有相当的3D方面的经验但还需要一点方向指引的人而写的。这些并不是什么你必须使用的硬性的规定。这些只是我的一些心得体会,也以此从宏观上也说明了游戏引擎由几个组成部分,每个组成部分包括多少工作量。我把这些部分分为系统、控制台、支持、渲染器/引擎内核、游戏界面、游戏本身以及工具/数据。

Tools/Data 工具/数据
During development, you're going to need some data, and unfortunately it's not going to be as easy as writing some text files that define a cube. At the least you will need 3d model editors, level editors, and graphics programs. These things can be bought or you can find a free program online that does the same type of thing. Unfortunately you're probably going to need more tools than this and the software doesn't exist yet. You need to write it. You may end up writing your own level editor if you can't find one that does the things you want. You'll probably need to write some code to pack files into an archive since dealing with and distributing hundreds or thousands of files can be a pain. You'll need to write converters or plug-ins from your 3d model editor format into your own format. You'll need tools to process game data, such as visibility computations or lightmaps.

在开发过程中,你将会需要一些数据,不幸的是,这个并不像写若干文本文件来定义一个立方体那么简单。起码你会需要3D模型编辑器、关卡编辑器和图形程序。这些东西可以花钱买或者去可以去网上下载一个免费的程序做这个工作。然而更不幸的是,除了这些,你可能还会需要更多的工具,而这些软件根本就不存在。因此,你需要自己写出它们。如果你不能弄到一个能满足你需要的关卡编辑器,你可能得动手自己写一个。你还可能会需要写一些代码来把很多零零碎碎的文件打成一个文件包,因为,处理和发布成百上千的文件实在让人头疼。你还需要写个转换器或者插件来把3D模型编辑器的格式转换到你自己的格式。还有一些处理游戏数据的工具,比如可见性计算或者光照纹理映射等等,也是必不可少的。

The basic line is that you'll probably have nearly as much or more code in tools than actual game code. You can find formats and tools that you can use, but sooner or later you'll realize you need some things that are very custom to your engine and you'll end up writing your own anyway.

一个基本要点是:在编写工具上所花费的代码量很可能会达到甚至超过编写游戏本身的代码量。你可以找到一些能被利用的格式和工具,但迟早你会认识到,你需要一些专门针对于你自己引擎的东西,于是不得不放弃这些现成的东西而自己另起炉灶。

Although there is a probably a big rush to get tools done just so there are usable, do take care in your coding. Someone may actually try to use, extend or modify your tools one day, especially if you make your engine to be opensource or modifiable.

虽然完成这些工具并使其便于使用将会是一个漫长的冲刺过程,但是你得注意整理你的代码。总有一天,某人可能会试图使用、扩展或者修改你的工具,尤其是当你的引擎是以允许自由修改的或以开放源代码的方式来发布的时候。

You should probably be prepared to spend as much time making graphics, levels, sound, music and models as you did writing the game, tools, and engine.

正如编写这个游戏、工具以及引擎这些工作一样,你就应做好花费大量时间在编辑制作图形、关卡、音效、音乐和模型等工作上的准备。

System 系统
System is the part of the engine that communicates with the machine itself. If an engine is written very well the system is the only part that should need major modifications if porting to a different platform. Within the system are several sub-systems. Graphics, Input, Sound, Timer, Configuration. The System is responsible for initializing, updating, and shutting down all these sub-systems.

系统是引擎中负责与机器本身进行交流的部分。如果引擎编写得十分精良,则在作平台移植时,只有系统部分是需要作主要修改的地方。系统内部又分了几个子系统。包括图形、输入、声音、定时器、配置。系统负责初始化、更新、关闭所有这些子系统。

The Graphics Sub-System is pretty straightforward. If it deals with putting things on the screen, it goes here. One would most likely write this component using OpenGL, Direct3D, Glide, or software rendering. To get even fancier, you could implement multiple API interfaces and put a Graphics Layer on top of them to give users more choice and more chance for compatibility and performance. This is a bit difficult though, especially since not all API's will have the same feature sets.

图形子系统的概念非常直观易懂。我们通过它来把图象在屏幕上显示出来。通常,我们会用OpenGL,Direct3D,Glide或者软件渲染来实现这个部分。如果想更酷的话,可以把这些API界面都给实现了,然后在它们上面设计一个图形抽象层,这样就给了用户更多的选择和机会来提高兼容性和性能。当然,实现这个并不是一件很容易的事情,因为不是所有的API都具有相同的特性集。

The Input Sub-System should take all input (Keyboard, Mouse, Gamepad and Joystick) and unify it and allow for abstraction of control. For example, somewhere in the game logic, there will be a need to see if the user wants to move his or her position forward. Rather than doing multiple checks for each type of input, one would make one call to the input sub-system and it would transparently check all devices. This also allows for ease of configuration by the user, and easily having multiple inputs perform the same action.

输入子系统负责处理所有的输入(键盘、鼠标、游戏手柄和游戏摇杆),并把它们统一起来以允许控制的抽象化。举例来说,当在游戏逻辑进行到某处的时候,我们需要检测玩家是否希望他或她的位置朝前移动。与其直接依次去检测每种输入设备,不如让我们来调用一次输入子系统,它会透明地去完成检测所有的输入设备的工作。这样还有一个好处就是使得玩家可以轻松地进行输入配置,并且可以很容易地实现由多种输入控制同一动作的功能。

The sound system is responsible for loading and playing sounds. Pretty straight forward, but most current games support 3D sound and this will make things a little more complex.

声音子系统负责加载和播放各种声音。相当直观吧,但当前绝大部分游戏都支持3D音效,这使得整个工作变得稍微复杂了一些。

Pretty much everything in a 3d game engine (I'm assuming real-time games here...) is based on time. Hence you need some time management routines in the Timer sub-system. This is actually pretty simple, but since anything that moves will move with time, a decent set of routines will keep you from writing the same code over and over.

3D游戏引擎(这里我指的是实时3D游戏……)中的绝大部分功能都需要基于时间来进行。因此在时间子系统里你必须实现一些时间管理功能的代码。这个其实非常简单,但因为所有东西的移动都是按照时间来进行的,一套设计优良的系统将使你不必在以后反复重写多次雷同的代码。

The Configuration unit actually sits above all the other sub-systems. It's responsible for reading configuration files, command line parameters, or whatever setup method is used. The other sub-systems query this system when they are initializing and running. This makes it easy to change resolution, color depth, key bindings, sound support options, or even the game that gets loaded. Making your engine very configurable just makes it easier to test and allows users to set things up the way they like.

配置子系统实际位于前述子系统之上。它负责读取配置文件、命令行参数、或者其它被用到的设置方式。其它子系统在初始化和运行的时候会向它查询相应配置。这样就可以很容易地改变分辨率、颜色位深、键设置、声音支持选项等等,甚至是在游戏已经加载了以后。使你的引擎尽可能是可配置的,这样可以简化测试并使得玩家更易于把游戏设置成他们自己所喜爱的方式。

Console 控制台
Ok, I know everyone likes to follow the crowd and have a console like Quake. But it's really a good idea. With console variables and functions you can change settings in your game and your engine without restarting it. It's wonderful for outputting debug information while developing. Often times you'll be needing to examine some variables and outputting the to the console is faster and sometimes better than running a debugger. Once your engine is running, if an error occurs, you don't have to quit the application; you can handle it gracefully and just print an error message. If you don't want your end user to see or use the console, its easy to disable it and no one is the wiser that it's still there.

好的,我知道大家都喜欢随大流去做一个像Quake那样的控制台。但它确实是个好主意。通过控制台变量和函数,你可以在不重新启动的情况下改变游戏和引擎的设置。能在开发时输出调试信息也是一件很棒的事情。很多时候,你需要检查一些变量,把它们的值输出到控制台上比使用调试器方便得多。一旦引擎开始运行,如果有错误发生,不必退出这个应用程序,你可以很轻松地处理它并输出一条错误信息。如果你不想让最终用户看到或使用控制台,你可以很容易地将它屏蔽掉,没人能看得出它的存在。

Support 支持
This is a system that is used by pretty much every other system in the engine. This includes all your mathematics routines, (vectors, planes, matrix, etc), memory managers, file loaders, containers (or use STL if you don't roll your own). This stuff is pretty basic and will probably be used in most any project you ever are involved in.

这个系统会被引擎的其他部分大量使用。它包括你全部的数学代码(向量、平面、矩阵等等)、内存管理、文件加载、容器(如果偷懒,可以用STL)(译者注:应该尽量用STL而不用自己写的容器)。这个部分非常基础,很可能在其他工程中你都会用到它。

Renderer/Engine Core 渲染器/引擎内核
Ah yes, everyone loves rendering 3D graphics. Because there are so many different methods of rendering 3D worlds, it's nearly impossible to give a description of a graphics pipeline that works in all situations.

耶,人人都爱渲染3D图形。因为渲染3D世界的方法是如此之多,以至于几乎不可能给出一个在所有情形下都能工作的图形管道的描述。

Regardless of how you implement your renderer, the most important thing is to make your renderer component based and clean. Make sure you have distinct modules for different things. The sub-sections that I break the renderer into are sections like Visibility, Collision Detection and Response, Camera, Static Geometry, Dynamic Geometry, Particle Systems, Billboarding, Meshes, Skybox, Lighting, Fogging, Vertex Shading, and Output.

不管你是怎么实现渲染器的,最重要的事情就是让渲染器组件基本并且明白。确保你对应不同的状况有清楚的模块。我把渲染器再次细分为可见性、碰撞检测和响应、摄象机、静态几何图形、动态几何图形、粒子系统、公告牌、网格、天空盒、光照、雾化、顶点光影和输出。

Each one of these sections needs to have an interface that easily allows for changes in settings, position, orientation, or any other setting that may be associated with the system.

其中每个部分应该各自有一个接口,我们可以通过这个接口来方便地改变设置、位置、方向、及其它任何与系统相关的部分。

One major pitfall to look out for is feature bloat. Decide what you are going to implement at the design stage. If you don't, adding new features will start to get hard to do and the solutions will be kludgy.

可以预计,将会遇到的一个主要缺陷是特性膨胀。所以,尽量在设计阶段先确定好哪些是你打算实现的。否则的话,增加新特性会变得非常困难的,即使最后能得以实现,但也肯定会是非常勉强的。

One thing that is nice and convenient is to have all triangles (or faces) ultimately pass through the same point in the render pipeline. (Not a triangle at a time, I'm talking about triangle lists, fans, strips, etc.) It takes a bit more work to get everything into a format that can be passed through the same lighting, fogging, and shading code but in the end you'll be happy that any effect that you can do to one polygon can be done to any polygon in your game simply by changing its material/texture id.

一个漂亮而方便的设计是让所有的三角形(或者称为面也行)最终通过相同的一点进入的渲染管道。(不是每次一个三角形,我说的是三角形列表、扇形、条带等等)。把所有的东西统一成为一个格式需要多做一些工作,而这个格式将被经过相同的光照、雾化、及阴影代码处理。但是最后,你会欣慰地发现,只要简单的改变一下多边形的材质/纹理索引,在一个多边形上可以实现的任何效果,都可以在游戏中其它任何多边形上实现。

It doesn't hurt to have multiple points from which things are drawn, but it can lead to redundant code if you're not careful.

这样做不会造成绘制的物体的点数成倍增加,但必须仔细以免产生冗余代码。

You'll eventually find out that all those cool effects that you wanted to implement will be 15% or less of the total code you end up writing. That's right, most of a game engine is not graphics.

最终你会发现,全部这些你打算去实现的很酷的效果在整个代码工作量中只占15%不到。这是很自然的,图形只占了游戏引擎的一小部分。

Game Interface 游戏界面
The most important part of a 3D game engine is that it is a game engine. It is not a game. The actual game should never have components that are put into the game engine. Having a thin layer between the engine and the game makes for cleaner code and ease of use. It's a little extra code, but it also makes a game engine very reusable and it becomes much easier to use a scripting language for game logic, or put the game code in a library. If you embed any of your game logic in the engine itself, don't plan on reusing it later without lots of problems and modifications.

3D游戏引擎中最重要的部分是――它是一个游戏引擎,而不是一个游戏。实际的游戏绝不应该包含任何被放入游戏引擎的部分。在引擎和游戏之间放入一个薄层可以使得代码更整洁并且易于使用。虽然要增加一点额外的代码工作量,但好处是可以让游戏引擎易于重用并且更易于使用脚本语言来实现游戏逻辑,或者是把游戏代码放入一个库中。如果你打算把游戏逻辑的任何一部分嵌入引擎,那么在以后计划对它进行重用时,你得准备着去面对无数的问题和修改。

So you're probably wondering what this layer between the engine and game provides. The answer is control. For each part of the engine that has any dynamic properties, the engine/game layer provides an interface to modify it. Some things in this category include the camera, model properties, lights, particle system physics, playing sounds, playing music, handling input, changing levels, collision detection and response, and placement of 2D graphics for a heads up display, title screen or whatever. Basically if you want your game to be able to do it, there must be an interface into the engine to do it.

那么,你肯定想知道,这个引擎和游戏之间的层应该提供些什么呢?答案是控制。对引擎中每个具有动态属性的部分,这个引擎和游戏之间的层都提供了一个接口去修改它。在这个范畴里包括摄象机、模型属性、光照、粒子系统物理、播放声音、播放音乐、处理输入、改变关卡、碰撞检测和响应,及2D图形的放置以实现一些覆盖内容的显示、标题屏幕等等。如果你要让你的游戏可以做这些事情,就必须有一个到引擎的接口来做这些。

The Game 游戏本身
Well, at this point, I can't tell you how to write your game. That's up to you. You've spent a while writing this amazing engine with a great interface that will make your game writing process less stressing.

呵呵,关于这个,我无法告诉你怎样去写你自己的游戏,这该轮到你自己了。你已经花了一些功夫去编写这个让人惊讶的引擎,它优良的界面将极大地减轻你在游戏编写过程中的压力。

3D game engines are huge software projects. A single person can write one, but it's not an overnight process. You're probably going to have more than a few megabytes of source code. If you're not motivated to finish it, you won't.

3D游戏引擎是一个巨大的软件工程。一个人可以搞定一个引擎,但肯定不是熬上一晚就能搞定的。你可能将会需要写几兆的源代码。如果你缺乏去完成它的动力,那是绝对不可能成功的。

Also don't expect to write a full engine on your first try. Pick a small project that has small requirements in the engine. Work your way up. You'll get there.
还有,千万别第一次就试着编写一个完整的引擎。不妨先选一个对引擎需求较少的小型工程。脚踏实地,你终将到达目标。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值