Skip to content

Latest commit

 

History

History
121 lines (103 loc) · 9.77 KB

2017-07-27-GameProgrammingGems0.markdown

File metadata and controls

121 lines (103 loc) · 9.77 KB
layout title subtitle date author header-img
post
游戏编程精粹第一卷阅读笔记
回顾游戏制作历史,希望制作出更好的游戏
2017-07-26 15:00:00 -0700
tachen
img/post-GameProgrammingGems0-bg-00.jpg

感悟

《游戏编程精粹》现在总共有八卷,从第一卷到第八卷,可以清晰看到游戏制作的发展历程,对于我来说,读完后,似乎又进步了一点点

第一卷:自研引擎时代


数据驱动

> 创建一个能按需解析文本文件的系统。这对于数据驱动设计的有效应用来说至关重要。 > 每个游戏都需要有一种清晰的方式读取通常意义上的数据,游戏最终是以二级制文件来读取的, > 但是在开发期间能以文本文件来读至关重要。文本文件如果是作编辑修改是没有什么实际意义的, > 它的真正意义在于——不用修改一行代码,你的整个小组,包括测试人员和游戏设计人员就能进行各种新尝试, > 并改变不同的东西来进行测试。这样,实现起来很简单的文本文件按需解析系统就成了一个必不可少的工具。

拥抱变化,由程序员开发数据编辑工具交给游戏设计人员,当游戏设计人员有新想法想要验证的时候不再需要通过程序员

C++面向对象编程

> 游戏程序员与典型的应用程序员有些不同,由于游戏程序员总是工作在最前沿的,要把人类和硬件的限制推到极限, > 因而他们往往更愿意改变甚至打破传统的程序设计原则。不幸的是,这种倾向常常会由于对基本OOP原则理解或实现的 > 不当而产生负面效应,产生不可维护的代码。 > > 随着游戏变得越来复杂,游戏公司希望通过复用更多的代码来减少持续增长的开发费用。随着公司对内容及游戏可玩性的关注, > 引擎授权变得越来越受重视了,而且在不久的将来肯定会成长为一个主要且独立的产业。这类开发工作相比以前的游戏开发来说, > 则要求更高的稳定性与长期的规划性。每做一个新游戏就完全废弃你以前的代码,这在不久的将来可是不行的。

面向对象的精髓:代码复用,提高稳定性
现在3D游戏引擎开发两大阵营:Unity3d、Unreal Engine4

模板元编程

> 该方法可以成为你C++工具包中的有用工具。你很可能会有指数级运行时间不能降为常数级运行时间的情况, > 通过使用模板元编程,就可以通过增加额外的编译时间来降低程序的运行时间。对于游戏来说, > 执行时间通常比编译时间更重要,所以这项技术也将非常有用。 > > 让我们退一步来说。模板元编程的确引人瞩目,且不可否认很高效,但是并没有很多游戏需要生成斐波那契序列 > 或数字的阶乘。就算有游戏需要,代码在编译期能确定输入参数的可能性也不大。这仅是单纯的C++小技巧, > 还是有使用价值的技术呢? > > 模板元编程有一个潜在的重要问题。当今(2000年)许多编译程序不能换算递归以及那些包含了基于模板的复杂算法的数学方法。 > 在正弦计算的例子中,按级数展开10项计算,每往下走一个或两个指令就需要编译程序换算近20次浮点乘法,50次整数乘法, > 20次浮点除法、10次浮点减法以及10次递归调用。编译程序“能”做到吗?当然可以。编译程序“应”做到吗?这就需要看具体情况了。 > > 我用Microsoft Visual C++6.0测试了前面的例子。VC6在斐波那契和阶乘模板中有很优秀的表现,而在正弦模板中却表现不佳, > 生成的代码甚至不如C运行时的sin()函数。在默认情况下,VC6将递归展开8层,且对计算不进行任何优化。 > 通过指定#pragmas inline_depth(255)和 inline_recursion(on),VC6对递归完全展开,并优化所有计算, > 从而还是幸运地得到了好的结果。 > > 以上说明,所有的优化方法都需要经过实际的证明。应该检验编译程序生成的代码,并计算引入模板之前和之后的性能。 > 你可能需要转变几个编译程序的标志以获取希望的结果。 > > 模板元编程的优势所在是处理矩阵运算。三维游戏中大量使用矩阵。将关键函数模板化能够显著地提高速度。 > > 当前版本的编译器在处理模板是仍有很多限制,特别是处理递归模板。编译器模板错误信息从含义模糊到难以辨认的都有。 > 对任何优化来说,都是在时间和空间上求得平衡。对大多数情况,模板元编程可以生成最好的结果:最小并且最快的代码。 > 对其他情况,展开代码将比原有代码显著增大,这将降低或抵消带来的速度优势。不过可以预期,模板元编程将在C++库 > 和游戏开发中扮演重要的角色。

get新技能

一个通用的函数绑定接口

> 脚本引擎和网络消息传送有一个很重要的共同点,那就是它们都要求以类型安全、有效且便利的方式与游戏的功能接口(交互)。 > 本文提出了一种方法,可以导出函数并在运行时进行动态绑定,而且不会牺牲运行速度。 > > 对脚本引擎的基本要求是,可以调用函数并传递其参数。为此,我们需要需要知道这个函数的名称、它在内存中的位置以及它带有的参数。 > 这些参数的类型,作为语言的一部分,必须是脚本引擎直接支持的类型。我们假定支持的类型有bool、float、int、string和void。 > > 对网络RPC(远程过程调用)的基本要求是,可以从远程机器上调用函数并传递其参数。考虑到我们的机器很可能在不同的内存地址上运行代码, > 我们不能直接在网络上传递函数指针,而必须将它们转换成一种两边都能识别的标记。我们使用序列ID来表示,这种序列ID可以快速地与实际的 > 函数指针进行互换。另外,我们还需要知道如何识别出参数中的字符串和内存指针,这样才能将它们指向的数据包裹进RPC块的末端, > 以便在网络上进行传递 > > 这些工作看上去好像并不必要。对于小输出集的小型项目来说,可能的确是。但稍大型的项目很可能要经常改变。 > 一旦基础工作做好了,向系统添加新函数就如同标记它们为输出一样简单,并且这些新函数能立即可用。 > 这个过程不仅本身值得去做,它还可以成为开发团队各方面能力的强大推进力量。当与基于一般用途的脚本引擎结合的时候, > 除了能够依照本来编写的意图服务于特定内容需求以外,它还可以成为一个有用的调试工具。

现在函数绑定和RPC已经成为了标配,但是了解一下怎么实现还是蛮有意思的

快速数据载入技巧

> 如何变得更快是游戏编程中永恒的挑战。无论何时,一旦你让某人凝视屏幕并等待,你就中断了信息流并有流失玩家的风险。 > 但随着游戏关卡变得越来越大,你所需要的载入时间也变得越来越长。本节的技巧可以减少你的游戏关卡载入时间。 > > 在所有你能做的事情里面,最重要的是尽你所能去预处理关卡数据(level data)。这可以通过使用独立的工具程序, > 如用来编辑游戏数据的独立关卡编辑器,或者在游戏开发中自定义的数据,打包代码。我曾经针对同一游戏的不同部分, > 分别使用了这两种方法,都获得很好的结果。 > > 为了最终获得更短的数据载入时间,需要将你的数据预处理为游戏中最终使用的格式。只需要做些计划,你就可以让你的C++类 > 或C结构的布局更适合高速载入。 > > 对于某些游戏控制台硬件,至少有一件非常重要的事情需要注意。一些系统总是要读完当前磁盘扇区。例如,Sony PlayStation从CD-ROM读取的数据 > 一定是2048字节的倍数,那你就破坏了紧接在那个结构之后的内存数据。我们称之为“memory stomp”。 > > 为避免这种memory stomp,需要有一个足够大的临时缓冲区来保存填充到2K边界的数据文件。如果你需要读多个文件,不要每次都分配和释放一个新的缓冲区。 > 而是改用一个最大缓冲区,只分配一次,并且在所有的读取操作中重用它。在完成所有的读取操作后再释放它。

c++序列化与反序列化和IO优化

小波:理论与压缩

> mipmap理论基础。小波常用于图像压缩,整个图像可以从任何一级被重新精确组合。但是这对于压缩是毫无意义的,故而我们能舍弃一些值以丢失可能的最小的信息。 > 简而言之,具有极少细节的区域被大幅度地压缩,而有很多细节的区域则压缩很少。因而,失去的信息在视觉上就几乎感觉不到了。

想起很早前在南昌的时候公司有开发过图片压缩的算法

矢量摄像机

> 矢量摄像机是用于软件或硬件3D渲z染引擎中表现摄像机运算的一个便利的方法。它的简单性提供了直观地放置和操作摄像机的自由度。 > 摄像机能够在本地坐标空间工作允许进行几种众所周知的优化,以获得比用传统的基于矩阵的摄像机更大的渲染速度。矢量摄像机增长了25% > 的帧速率。通过减少需要变换的数目,计算较小的用于最终显示的数据包,并使用一个较低的总内存量来达到这个目的。映射运算十分灵活, > 最好的优化就是重新设计方法,而不是对现有的方法进行可怜的压榨!

小结

游戏的魅力就在于:如果有追求,根本停不下来!