4

我正在为 Motion 和 FCP X 开发一些 FxPlug 插件。最终,我想让它们在 Metal 中渲染,因为 Apple 正在弃用 OpenGL。

我目前正在使用 CoreImage,虽然我已经能够使用 CoreImage 功能在 FxPlug SDK 之外进行金属处理,但 FxPlug 只为我提供了作为 OpenGL 纹理的帧。我试过把它传递给 CoreImage 过滤器,但我最终得到了这个错误:

Cannot render image (with an input GL texture) using a metal-DG context.

经过一番研究,我发现我应该可以使用 CVPixelBuffers 在两者之间共享纹理,但是在尝试使用这种方法编写代码一段时间后,我开始相信这是一种编写方式(如,从头开始创建)到共享缓冲区,但不能在两者之间转换。虽然这可能不正确,但我找不到让现有 GL 纹理存在于 CVPixelBuffer 中的方法。

TL; DR:我找到了从 CVPixelBuffer 获取结果 Metal 或 OpenGL 纹理的方法,但我找不到从现有 OpenGL 纹理创建 CVPixelBuffer 的方法。我的心不在这种方法上,因为我的最终目标是简单地从 OpenGL 转换为 Metal,然后再转换回 OpenGL(理想情况下以一种有效的方式)。

有没有其他人找到使用 FxPlug 和 Metal 的方法?有没有一种从 OpenGL 纹理转换为 Metal/CVPixelBuffer 的好方法?

4

1 回答 1

1

我编写了一个同时使用 OpenGL 纹理和金属纹理的 FxPlug。您正在寻找的是一个IOSurface. 它们是可以与 Metal 或 OpenGL 一起使用的纹理,尽管它们有一些限制。因此,如果您已经拥有 Metal 或 OpenGL 纹理,则必须将其复制到 anIOSurface中才能与其他系统一起使用。

要创建一个,IOSurface您可以使用CVPixelBuffers (通过包含kCVPixelBufferIOSurfacePropertiesKeyIOSurface ) ,也可以直接使用<IOSurface/IOSurfaceObjC.h>.

一旦你有了,你就可以通过从通孔(在 中定义)IOSurface获取一个 OpenGL 纹理来将你的 OpenGL 纹理复制到其中。然后,您获取该纹理并将其用作 FBO 的背景纹理。例如,您可以使用输入作为纹理在其中绘制一个带纹理的四边形。完成后一定要打电话!IOSurfaceCGLTexImageIOSurface2D()<OpenGL/CGLIOSurface.h>FxTextureglFlush()

接下来通过(在此处描述)获取并从中IOSurface创建一个。您需要创建一个输出来绘制并从中创建一个。将您的 Metal 渲染到输出中。接下来,获取输出并通过. 现在将该 OpenGL 纹理复制到输出 FxTexture 中,方法是使用它作为纹理支持的 FBO 的支持或您喜欢的任何其他方法。MTLTexture-[MTLDevice newTextureWithDescriptor:ioSurface:plane:]IOSurfaceMTLTextureMTLTextureIOSurfaceCGLTexImageIOSurface2D()

如您所见,这样做的缺点是每次渲染都需要 2 个副本 - 1 个输入到应用程序提供给您的输出纹理中IOSurface,1 个输出IOSurface到输出纹理中。另一个缺点是这可能完全没有实际意义,因为苹果已经公开宣布他们将停止对 OpenGL 的支持,他们可能已经在研究基于 Metal 的解决方案。自己做这一切可能是额外的工作。(虽然好处是您可以在仅支持 OpenGL 的其他主机应用程序中使用相同的代码。)

于 2019-01-22T06:20:39.563 回答