玩具引擎开发日志#1

在过去的几周里,作为我的本科论文的一部分,我一直在业余时间(基本上是周末和假日)从事玩具游戏/图形引擎的工作。 它不是要成为“准备就绪”的引擎或用于商业游戏,而是要成为我的图形和引擎编程实验的平台,对于我的论文,它将用于测试和基准测试一些基本的并行渲染技术。 Direct3D 11和Direct3D12。我还利用这个机会来测试一些有趣的“ 流行语 ”,这些流行语游戏开发社区中很流行,例如实体组件系统(ECS),面向数据的设计和基于任务的并行性。 我将尝试在一些常规开发日志中发布有关此玩具引擎开发的有趣信息。

到目前为止我做了什么

到目前为止,我所做的大部分工作都是关于玩具引擎的核心体系结构的,例如定义接口,实现许多用于记录日志,错误处理,资产加载等的助手。 自上次使用C ++编写代码以来已经有一段时间了,因此我还花了一些时间来记住和学习有关该语言的新知识。

精英

首先,我决定将ECS用作运行时模型,其基本目标是数据和逻辑分离,因此组件只是数据容器(存储在缓存友好型存储中),每个实体都有一些组件(例如,一个角色可能具有变换组件,网格组件,健康组件,碰撞体积等),每个系统都会查询具有某些特定组件的实体,例如,物理系统可以查询具有碰撞体积的实体并检查是否有碰撞。 如果您想了解有关ECS实施的更多详细信息,那么本文很棒。

我决定不花很多时间在自己的ECS实施上,因此我使用了一个很棒的开源ECS库:entityX。 我没有将其用作外部库,而是将其作为核心代码的一部分,因为我对其进行了一些修改,重命名了一些方法来遵循我定义的代码样式,并且将来希望在某个时候集成消息队列系统如果我认为可以改进的话,甚至可以更改系统的实现。

渲染器

由于Direct3D 12的“接近金属”方法,我决定不像大多数游戏引擎一样为这两个API实现与API无关的单个包装,而是我在研究两个不同的渲染器,其中一个更高的渲染器由D3D实现11和另一个充分利用Direct3D 12的较低级API的优势(至少是计划)。 两个渲染器都与引擎的其余部分共享一个非常简单的界面,基本上,ECS系统(渲染系统)将用所有必要的数据填充数据容器(帧数据包)以渲染一帧,例如网格参考,照明数据,和时序信息,该数据包将被提交给活动渲染器,然后渲染整个帧。 我选择这种方法的灵感来自Bungie出色的GDC演讲,因为我的意图是使我的实现完全并行化,因此在数据提取阶段并由渲染器处理它似乎是合理的。 当它变得更加成熟时,我可能会写一篇有关该体系结构的详细文章。

我正在使用很棒的开源tinyobjloader库来加载网格物体的obj文件和用于phong材质的mtl文件,这真的很简单,并且我能够使用它成功加载大的场景,例如梯级。 现在,我正在使用DirectX 11渲染器的非常初步的版本进行测试,它使用的是简单的着色器,该着色器基本上在网格上应用了漫反射纹理。 这是非常基础的,但是我认为足以测试我的帧数据包实现是否正常工作。 这是它渲染房屋和迷失帝国场景的两个屏幕截图:

目前,我正在研究DirectX 12渲染器。 它的“接近金属”方法非常强大,但是也很难使工作有效地进行。 管理资源分配和过渡非常困难,我特别试图选择处理动态缓冲区的最佳方法,我想我最终将使用本文所述的环形缓冲区。

接下来我要做什么

在论文完成之前,我还有很多事情要做(祝我好运)。 这些是其中一些:

·DirectX 12渲染器:其实现至少需要与基本DirectX 11实现相匹配

·分析代码:我仍然需要定义如何配置CPU和GPU时间,我想我将首先通过渲染代码传播PIX的标记。

·亲爱的IMGUI集成:我的计划是使用这个很棒的即时模式GUI库显示调试信息,并允许在运行时进行小的配置调整。

·更好的着色器:实现适当的着色器和材质,我想使用mtl文件数据来实现至少具有适当照明的Blinn-Phong着色子集。

·线程池:实现或选择一个好的线程池库。