在C ++中处理C代码(Vulkan)

时间:2017-10-09 11:11:30

标签: c++ c design-patterns vulkan

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

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

上述有趣的一点是它有一个叫做逻辑设备的东西,它是对显卡的抽象参考。

它可以在任何地方使用,以下列方式创建和分配:

  1. 使用创建信息创建结构
  2. 创建代码将输出到
  3. 的变量
  4. 调用实际的vkCreateSomething或vkAllocateSomething函数,传入逻辑设备, 创建信息和对输出的引用,以输出并检查它是否成功。
  5. 我自己说这种风格没有任何问题我说。它只是在OOP中根本不是很方便,因为它依赖于随处可用的逻辑设备。

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

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

2 个答案:

答案 0 :(得分:4)

逻辑设备是实际依赖项。

它具有状态,并且其状态需要可用于使用硬件。

您可以将它用作操作的参数,存储在几乎所有类中的值,全局或monadic-esque" final"参数,其中每个操作只返回仍需要设备运行的东西。您可以用返回(指针/引用)它的函数替换它(指针/引用)。

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

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

结果组合操作将有一个设置(你可以绑定逻辑设备和你可以做的任何事情"早期"在你需要准备昂贵的缓冲区之前)和执行阶段(你在哪里)给它提供昂贵的缓冲区并生成输出。)

或者作为另一种方法,从找到一个带有协程支持的编译器,并在程序上将其写为异步。

答案 1 :(得分:0)

Vulkan是一个OOP API。它不是基于类的,因为它是C99而不是C ++。使用官方Vulkan-Hpp可以很容易地解决这个问题。您可以将其作为半职级LunarG Vulkan SDK的一部分vulkan.hpp使用。

使用情况与vulkan.h不同:您可能有Device实例的成员指针/引用,或者每个对象都有VkDevice个句柄成员需要它。某些更高级别的对象将处理逻辑设备的生命周期(例如您的RenderingEngine类等)。差异几乎只是美学:你会使用device->command(...)而不是vkCommand(device, ...)vulkan.hpp似乎没有通过构造函数/析构函数使用正确的RAII,这是一种耻辱。

或者,引擎的用户可以管理设备。虽然与OpenGL不同,但这并没有多大用处。如果用户也希望使用Vulkan,则可以创建自己的VkInstanceVkDevice

  

我在Vulkan应用程序的教程/代码片段中看到的反复出现的模式是,大多数代码都是在一个非常大的类中。

这并不是特别针对Vulkan的。如果你考虑一下,几乎所有的C ++应用程序都是一个大的类来做所有事情(唯一的区别在于程序员难以从它委托给其他类实例)。