mre*_*dig 5 opengl core-image metal cvpixelbuffer
我正在为 Motion 和 FCP X 开发一些 FxPlug 插件。最终,我想让它们在 Metal 中渲染,因为 Apple 正在弃用 OpenGL。
我目前正在使用 CoreImage,虽然我已经能够使用 CoreImage 功能在 FxPlug SDK 之外进行 Metal 处理,但 FxPlug 只向我提供帧作为 OpenGL 纹理。我尝试将其传递到 CoreImage 过滤器中,但最终收到此错误:
Cannot render image (with an input GL texture) using a metal-DG context.
Run Code Online (Sandbox Code Playgroud)
经过一番研究,我发现我应该使用 CVPixelBuffers 在两者之间共享纹理,但是在尝试使用这种方法编写代码一段时间后,我开始相信这是一种 WRITE 的方式(如从头开始创建)到共享缓冲区,但不在之间进行转换。虽然这可能不正确,但我无法找到一种方法来使现有的 GL 纹理存在于 CVPixelBuffer 中。
TL;DR:我已经找到了从 CVPixelBuffer 获取生成的 Metal 或 OpenGL 纹理的方法,但我找不到从现有 OpenGL 纹理创建 CVPixelBuffer 的方法。我并不打算采用这种方法,因为我的最终目标是简单地从 OpenGL 转换为 Metal,然后再转换回 OpenGL(理想情况下以有效的方式)。
还有其他人找到了将 FxPlug 与 Metal 一起使用的方法吗?有没有好方法从 OpenGL 纹理转换为 Metal/CVPixelBuffer?
我编写了一个同时使用 OpenGL 纹理和 Metal 纹理的 FxPlug。您正在寻找的东西是一个IOSurface. 它们是可与 Metal 或 OpenGL 一起使用的纹理,尽管它们有一些限制。因此,如果您已经有 Metal 或 OpenGL 纹理,则必须将其复制到 以便IOSurface在其他系统中使用。
要创建一个,IOSurface您可以使用CVPixelBuffers (通过包含kCVPixelBufferIOSurfacePropertiesKey),也可以使用IOSurface中定义的类直接创建一个<IOSurface/IOSurfaceObjC.h>。
一旦有了,您就可以通过从via (在 中定义)IOSurface获取 OpenGL 纹理来将 OpenGL 纹理复制到其中。然后,您将该纹理用作 FBO 的背景纹理。例如,您可以使用输入作为纹理在其中绘制纹理四边形。完成后一定要打电话!IOSurfaceCGLTexImageIOSurface2D()<OpenGL/CGLIOSurface.h>FxTextureglFlush()
接下来获取IOSurface并从中创建一个MTLTexturevia -[MTLDevice newTextureWithDescriptor:ioSurface:plane:](此处描述)。您需要创建一个输出IOSurface来绘制并MTLTexture从中创建一个。将 Metal 渲染到输出中MTLTexture。接下来,获取输出IOSurface并通过它创建 OpenGL 纹理CGLTexImageIOSurface2D()。现在,通过将其用作纹理支持的 FBO 的支持或您喜欢的任何其他方法,将该 OpenGL 纹理复制到输出 FxTexture 中。
正如您所看到的,这样做的缺点是每次渲染都需要 2 个副本 - 1 个输入到应用程序为您提供的输出纹理IOSurface,1 个输出IOSurface到应用程序提供的输出纹理。另一个缺点是,这可能毫无意义,因为苹果已经公开宣布他们将终止对 OpenGL 的支持,他们可能已经在开发基于 Metal 的解决方案。如果全部由您自己完成,可能会需要额外的工作。(不过好处是您可以在其他仅支持 OpenGL 的主机应用程序中使用相同的代码。)