(1)基础调试
a) 日志及追踪,有些bug难以用VS自带的调试来进行单步调试,最好的解决方案就是printf调试法,打印一组数据,观察情况。之前我的做法是单独生成一个控制台,不过VS自带了一个OutPutDebugString()的方法,可以打印调试信息。不过这个只支持char*内容,我们可以将这个函数加工一下,使其支持不同类型的数据,甚至可以使其接受可变参数个数。
b) 冗长级别:我们有时想要打印,有时又不想打印,所以可以设置打印内容的级别,每个信息设置一个级别,然后设置一个全局的级别,大于这个级别的打印,然后可以通过调节全局级别,控制打印内容的范围。
c) 频道:再扩展的想一想,有很多要打印的内容时,就会比较乱,那么,将不同模块的打印信息分成不同的频道就可以解决问题了,再增加一个频道的参数,就可以控制打印哪个频道的相关信息啦。
d) 日志:有时候程序会莫名的崩掉,这时候就不单单要只看打印信息了,我们需要将程序的执行过程写入日志文件来供运行后查看结果。这里有个纠结的地方,如果每次打印都输入到日志文件,会保证日志的完整性,但是会损失性能,如果缓冲满了才输出到日志,有可能程序崩了就没办法将缓冲区的内容输出了,所以这是个取舍的问题。
e) 崩溃报告:崩溃报告也是一种日志,不过是程序崩溃时才有的日志,多数操作系统有一个顶层的异常处理函数,可以在此函数中打印各种异常信息,甚至发送电子邮件给程序团队(这个有点6啊),这些异常信息包括玩家状态,关卡,正在运行的脚本,堆栈信息等等帮助我们发现bug的信息。
(2)游戏中特有的调试功能
上面的一般的程序也可以使用,不过下面的这个应该是游戏中特有的东东了,绘图调试。
游戏几乎全是数学内容驱动的,我们用数学来定位物体,比如碰撞检测,投射光线,检测视线等等,如果我们这些东东都打印出来,一方面特别麻烦,另一方面也不好观测,更好的解决方案是用绘图将信息绘制出来,比如一个包围盒,那就把它画出来,正所谓一图顶千言,画面是最好的表现方式。
调试绘图API:应该简单易用,图形包扩直线,球体,点,坐标轴(x红色,y绿色,z蓝色),包围盒,文本。最好加上可以控制颜色,线的宽度,球体半径,坐标轴长度等的功能。
我们可以通过参数调节这些图元的位置,大小等等,自由度很高。而且这些内容可以使用一个DebugDrawManager类来进行管理,将调试绘图内容添加到调试内容队列中,在渲染时一起渲染出来。
(3)游戏内置菜单,或者主控台也是很好的选择,我们可以通过菜单或者控制台在游戏中对游戏进行控制,如果支持强大的脚本语言,甚至可以操纵整个游戏。比如一个AI,可以去掉其AI,改用手动控制AI以达到调试的目的。
(4)我们在调试游戏的时候,可以给人物手动添加点buff,比如去掉碰撞检测,移动到任意场景。
(5)摄像机移动:有时在调试游戏时,从某个角度我们不能很好的看到游戏的情况,所以我们可以设计一个在游戏暂停运行时也可以移动的摄像机来帮助我们调试。
(6)截屏也是一个很重要的调试方法,有些时候我们不能很好的重现bug,这种情况下截图或者屏幕录制就可以很好的帮我们定位bug。
(7)性能检测:游戏是实时系统,保证FPS很重要,我们要把握好性能,一种方法是查看函数的调用时间,一方面是函数本身的执行时间,另一方面则是函数的调用次数。
(8)如果资源载入失败,应该给出明确的Log提示信息,或者直接在游戏中显现出来。
(9)内存以及内存泄露检测也是很重要的。
渲染引擎是游戏引擎中的重中之重,同时也是最难的部分。作为一个图形学,DX还没怎么学的小白,表示这一章并看不懂多少,只是知道一些概念,得继续恶补了。
(1) 首先就是介绍3D世界构成的那些元素:顶点,三角网格,光照,材质纹理,光照模型,摄像机,光栅化,Z缓存,抗锯齿等等。
(2) 渲染管道:渲染的架构是基于管道(pipeline)的,管道最大的优势就是并行性,各个阶段的计算同时进行,极大的增大了渲染系统的吞吐量。
(3) 渲染管线广义上的划分:
a) 工具阶段(脱机):定义几何体和材质
b) 资产调节阶段(脱机):调节几何体和材质数据,使之变成引擎可用的格式
c) 应用程序阶段(CPU):识别出潜在可视的网格实例,将他们及其材质送至图形硬件以供渲染。
d) 几何阶段(GPU):顶点变换,光照,投影至齐次裁剪空间
e) 光栅化阶段(GPU):三角形转化为片段,对片段着色。经过多重测试(深度测试,alpha测试,模板测试等)最终和帧缓冲融合。
(4) 在渲染之前设置世界矩阵,光源方向矢量,纹理绑定,纹理寻址及过滤模式,基于时间的纹理滚动或动画效果,深度测试(禁用或者启用),alpha混合选项。在提交图元之前要进行设置,绘制只有有时需要还原设置。如果我们忘记了,则会造成渲染状态泄露,即上一个图元的渲染状态影响了下一个图元的渲染状态。
(5) 设置渲染状态是全局的,对整个GPU有效,改变渲染状态时,整个GPU管道必须完成工作才能换上新的设置,所以对于渲染的顺序一定要把握好,不然会有性能损失。最好是按照材质排序来渲染,但是如果按材质来,又会有overdraw即重复渲染同一个像素。解决的办法是使用GPU的深度预渲染步骤(z prepass),即第一次迅速产生深度缓冲内容,第二次才用完整的颜色填进帧缓冲。
(6) 场景图(scene graph):所谓场景图不是图,而是管理场景中对象的数据结构,在平头截体剔除之前先进行显示对象剔除,通常为四叉树,八叉树,BSP树,kd树,空间散列技术等。四叉树和八叉树使用的是递归的思想,将场景不断细分,查询的开销维持在最小。BSP树使用一个平面将空间平分,即传说中的二元空间分割树。
BSP树或者入口系统:用于室内环境
四叉树:室外平坦地形,上帝视角
额外剔除机制:室外大场景,第一人称或第三人称游戏
(7) 好吧,剩下的我基本都看不懂了…诸如:法线贴图,高动态范围光照(HDR),全局光照(GI),伽马校正,全屏后期处理(动态模糊,景深模糊,晕影,着色等等)
游戏引擎真的是博大精深,即使十年时间,也不一定能全部搞懂。做游戏简单,前提是有引擎。做一个引擎真的是太难了!
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/puppet_master/article/details/47303983