我正在尝试使用基于 Vulkan 的 C++ 编写渲染引擎。 Vulkan 是用 C 编写的,因此它有一些有趣的约定。

我在 Vulkan 应用程序的教程/代码片段中看到的一个反复出现的模式是,大多数代码都在一个非常大的类中。 (现在我的 vulkan 类也已经大约 2000 行了)。但是为了制作一个合适的渲染引擎,我需要将我的代码划分到一定程度。

前面提到的一个有趣的地方是它有一个叫做逻辑设备的东西,它是对显卡的抽象引用。

它无处不在,通过以下方式创建和分配事物:

  • 使用创建信息创建结构
  • 创建代码将输出到
  • 的变量
  • 调用实际的 vkCreateSomething 或 vkAllocateSomething 函数,传入逻辑设备,
    创建信息和对要输出到的变量的引用并检查它是否成功。

  • 我想说这种风格本身并没有错。只是它在 OOP 中一点也不方便,因为它依赖于随处可用的逻辑设备。

    我将如何处理这个问题?服务定位器和单例被许多人认为是可怕的解决方案(我可以理解),所以这似乎是我宁愿避免的事情。

    是否有设计模式可以解决这个问题?

    最佳答案

    逻辑设备是实际的依赖项。

    它有状态,并且它的状态需要可用于与硬件一起工作。

    您可以将其用作操作的参数、存储在几乎每个类中的值、全局或 monadic 式的“最终”参数,其中每个操作只返回仍然需要设备运行的内容。您可以使用返回(指针/引用)它的函数替换(指针/引用)它。

    考虑一下纯 OOP 是否是您想要做的; vulkan 和渲染更多的是关于操作而不是被操作的东西。我想混合一些函数式编程模式,这使得类似 monad 的选择更加合理。

    对缓冲区/数据进行组合操作。这些返回操作也需要缓冲区和数据。组合操作指定哪些参数是新输入,哪些是下一步使用的。这样做你可以(在编译时)设置一个类型安全的工作图,而无需运行任何东西。

    由此产生的组合操作将有一个设置(在你需要准备昂贵的缓冲区之前,你绑定(bind)逻辑设备和你可以“尽早”做的任何事情)和一个执行阶段(在那里你提供昂贵的缓冲区并生成输出)。

    或者作为另一种方法,从 c++2a 中找到一个具有协程支持的编译器,并以异步方式编写它。

    关于c++ - 在 C++ (Vulkan) 中处理 C 代码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46645069/

    10-11 16:06