考虑到我希望支持的两个库OpenGL和Metal,编写支持多个框架的渲染器变得特别困难,这两个库在显示方式上有很大的不同。 GPU。
我很好奇通常是如何针对可针对多种图形语言的应用程序设计其代码的。这是我可以做的事情的理论:
编写两个不同的渲染类,将数据和模拟内容保留在自己的区域中,只需更改渲染器即可。
高级诸如createTexture或copyTextureOnto之类的功能,并具有if语句,用于检查设备支持的语言并为其提供自定义实现。
创建与框架中的对象相似的图形对象(例如MTLCommandEncoder或MTLTexture) ),并使用它们来构建您的应用,并仅使用与您的图形框架匹配的植入即可。本质上是重新编码您使用的图形库之一的功能,然后在OpenGL支持设备上调用仅将if语句添加到实现中。
当您必须编写软件来支持多个图形库时您一般情况如何?您使用的技术会降低效率吗?
#1 楼
您可以通过抽象化基础技术来做到这一点。您知道,例如,在一个非常高的层次上,您将需要处理图像,几何图形,而且我猜您将不得不编写着色器来进行渲染。两个系统的纹理和几何形状可以采用相同的格式。因此,您可以设计用于渲染的界面。您可能会有一个包含几何的某种场景。几何可能会应用纹理。渲染几何图形时,您将需要使用着色器。这些可能是从抽象开始的好地方。您可能需要一个场景对象,其中包含要渲染的所有不同对象。每个对象都由几何图形和将应用于该几何图形的图像组成。 OpenGL和Metal之间的场景对象,几何对象和图像可以相同,因为它们都不特定于两者。 (我在这里假设几何图形只是浮点坐标,法线等的缓冲区,并且图像从CPU上的RGBA像素缓冲区开始。)
接下来,您需要提出了一种在希望使用的框架上在当前正在运行的硬件上呈现这些内容的方法。因此,您将创建一个抽象接口。也许您有一个
Renderer
对象。它将具有允许您添加带有图像的几何图形以用作纹理的方法。它将允许您将着色器与几何体相关联。它会提供一种将几何图形呈现为纹理或屏幕的方法。然后您可以继承
Renderer
类的子类(假设您使用的是C ++之类的东西),或者编写一个新类来实现Renderer
协议(如果您使用的是Objective-C或Swift之类的协议)。您有2个不同的子类或实现。一种使用OpenGL执行操作,另一种使用Metal进行操作。 因此,您可能会有一个
OGLRenderer
和一个MTLRenderer
。 OGLRenderer
类将通过创建顶点缓冲区对象并最终调用addGeometry()
来将几何实际上传到GPU来实现glBufferData()
方法。在您的MTLRenderer
中,您将通过MTLBuffer
创建一个-newBufferWithLength:options:
,然后使用memcpy()
将数据复制到缓冲区中。 因此,在编写应用程序的主要代码时,您将编码到
Renderer
接口,而无需知道实际上要使用的基础渲染器是否是OpenGL渲染器或金属渲染器。 (实际上,您甚至可以这样做,以便在某种程度上帮助它们在运行时进行切换。)您可以拥有一个工厂,可以根据您所使用的操作系统在运行时决定要使用的工厂,或者您可以通过仅包含适当的子类来在编译时决定。
评论
如果要查看多平台渲染器,可以检查一下