设计一个“渲染器”,除了OpenGL,使用其他API有意义吗?

3

我一直在思考,可能已经想太久了。目前,我有一个名为“Renderer”的抽象基类,它具有渲染和注册对象的虚拟方法(我必须注册对象以分配VBO的内存)。

然而,我不确定是否应该保持这样,我认为我应该保持基本的抽象类。我只是不会创建另一个“Renderer”来使用除OpenGL之外的其他API渲染我的对象。换句话说,我不会使用Direct3D或任何其他图形API,除了OpenGL。

但是我可能会有多个OpenGL渲染器的实现,例如针对OpenGL ES和普通OpenGL的实现(如果它们之间有很大的差异)。

如果我要使用另一个API,比如Direct3D,则创建上下文可能是我最关心的问题...我只是不确定如何以整洁的方式完成它。

如果这没有任何意义,对不起,我想我一直在思考太久了。

4个回答

1
利用3D API并不是一件容易的事情;我仍在为自己努力实现这一目标,尽管OpenGL支持大多数还是缺失的,因此API高度理论化,至少在我达到Direct3D实现的一个合适的里程碑,并找到一些关于OpenGL的好文档,以便我可以尝试构建OpenGL变体,看看我能走多远,以及我的多少假设实际上符合现实。
那可能是我惊讶地发现,通过现有的设计实现OpenGL只是小菜一碟,因为我是如此聪明 --- 或者(更有可能)当我决定完全放弃OpenGL(以及MacOS+Linux)时 :-)
我之所以能够这样做,是因为这是一个私人宠物项目,永远不会完成。对于任何有可能完成或需要完成的事情,我建议不要去做。这是很多工作。
你至少要做的事情包括:
  • 让你的API足够抽象,以至于两个渲染API之间没有应用程序可见的差异,同时不会失去性能(因此不要总是通过转换来做事情。在某些抽象数据集合中拥有一百万个顶点,并每次将其转换为Direct3D或OpenGL以获得最大的灵活性是很好的,但这只会给你一个幻灯片。因此,在我看来,前进的方式是让渲染API实际上使用更高级别的数据,如模型或场景,而不是顶点和三角形)

当然,对我来说一个主要问题是,我不仅仅是试图在不失去性能的情况下将Direct3D和OpenGL抽象化,我还试图沿途建立3D图形知识。这使得很难想出“最佳”设计,并需要大量的回溯。

  • 决定如何处理着色器(目前,我决定根本不处理它们,只需要求应用程序提供两种实现)。目前我的主要希望寄托在着色器上——假设一旦我解决了所有技术细节和API特定的东西,2012年的3D图形应该主要是在数据和缓冲区上运行着色器的问题。

当然,我可能完全错了,Direct3D / OpenGL可能真的是可以通过使用宏进行1:1映射来处理的相同事物,但我确定它不是那么简单。它仍然在相同的硬件上工作,具有固定的功能集,我甚至相信HLSL和GLSL足够相似,最终可以为两者制定一个统一的语言。

然而,我在这里写下所有这些话的原因是要打消你的念头。就我所知(猜猜看,你可能从未听说过我的名字 - 想想那意味着什么),这是相当具有挑战性的。


0

这取决于你想做什么。为什么要支持两个API?如果没有非常强烈的理由,我建议在Windows上使用D3D,在Linux上使用OpenGL。

你想做的事情可以使用一个抽象基类来定义渲染器的接口,然后有两个不同的实现,一个用于OpenGL,一个用于Direct3D,但这会增加虚函数调用的开销。

我添加了两个链接,讨论了这个主题。如果你不必支持多个API,只需选择适合目标平台的API即可。

http://www.gamedev.net/topic/160063-support-for-both-opengl-and-directx/

http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/striving-for-graphics-api-independence-r1672


0

我的问题总是:“即使我现在不想这样做,用另一种方式替换这个实现是否有意义?”

对于像字符串、向量或代表游戏中玩家的类之类的东西,答案可能是否定的。你可能会改变实现,但永远不需要更多。对于像渲染系统这样的东西,答案是肯定的。用不同的实现替换它确实是有意义的,因此,即使您永远不会这样做,编程到抽象是一个好主意。

当然,不要盲目应用规则,效率和源代码中的无杂乱也很重要,但我认为这是一个很好的指导方针。

话虽如此,我不会尝试将低级别的渲染内容抽象出来,因为这太难了。在渲染系统上如何提供可用的tesselation硬件的抽象呢?相反,我会在“绘制景观”、“绘制3D模型”、“绘制动画模型”等级别上进行抽象。

您可能永远不会实现第二个系统,但这样做是有意义的,因此请提供抽象,除非有积极的理由不这样做。


0

我不认为这很有用。因为你正在抽象化这一部分,所以对于库用户来说,底层API是Direct3D还是OpenGL并没有任何区别。它们在功能上是相同的,都可以做同样的事情。它们使用不同的编程模型,并基于不同的设计/营销策略,但它们中没有一个在任何方面根本上比另一个更优越。
两种API的粉丝之间经常发生争斗,但简单的事实是它们是相同的。

话虽如此,支持不同的后端的一个原因是可移植性。OpenGL除了上下文创建和一些细节(例如打开和关闭垂直同步)之外,已经可以在没有任何特殊要求的情况下进行移植。Direct3D只能在Windows和XBox下运行,这就是它的全部。

我个人不会考虑在OpenGL之外再做一个OpenGL ES后端,因为它可能是一个完全不同的东西,可能会让你的生活变得不愉快。当然,这非常取决于你打算做什么。

对于“简单”的事情来说,OpenGL ES在某种程度上就是“只是在你的手机上运行的OpenGL”。很棒,不是吗?听起来太好以至于难以置信。

对于“不那么简单的事情”,OpenGL ES总是缺少你用于某些效果的那个特定功能(对我来说是这样的,最终我放弃了它),并且会导致很大的困扰,需要找到一种温和的降级方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接