【问题标题】:How to Convert Existing OpenGL Texture to Metal Texture如何将现有的 OpenGL 纹理转换为金属纹理
【发布时间】:2019-05-18 15:28:12
【问题描述】:

我正在为 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.

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

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

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

【问题讨论】:

  • 您可以创建共享纹理并使用 OpenGL 从 FxPlug 提供的 OpenGL 纹理复制到该共享纹理,使用 Metal 对共享纹理执行任何其他操作,然后使用 OpenGL将其复制回 FxPlug 提供的纹理。
  • 我想我的问题是我不知道如何将它复制到共享纹理。你有任何示例代码吗? FxTexture 提供了(GLuint)textureId;(GLenum)target;,我发现没有办法利用其中任何一个复制到 CVPixelBuffer。

标签: opengl metal core-image cvpixelbuffer


【解决方案1】:

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

要创建IOSurface,您可以使用CVPixelBuffers(包括kCVPixelBufferIOSurfacePropertiesKey),也可以使用<IOSurface/IOSurfaceObjC.h> 中定义的IOSurface 类直接创建一个。

拥有IOSurface 后,您可以通过CGLTexImageIOSurface2D()(在<OpenGL/CGLIOSurface.h> 中定义)从IOSurface 获取OpenGL 纹理,将OpenGL 纹理复制到其中。然后,您获取该纹理并将其用作 FBO 的背景纹理。例如,您可以使用输入 FxTexture 作为纹理在其中绘制一个带纹理的四边形。完成后请务必致电glFlush()

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

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

【讨论】:

  • 我假设从主机应用程序提供的 FxTexture 开始,这将涉及您所说的将纹理复制到 IOSurface 的内容。在那种情况下需要使用 CVPixelBuffer 吗?我想知道的另一件事是,纹理复制是否有任何性能损失,或者金属整体是否弥补了这一点?
  • 是的,您需要复制发送到您的-renderOutput:withInput:withInfo: 方法的inputImage。它将涉及使用IOSurface,您可以根据需要通过CVPixelBuffer 创建它,但您也可以在没有CVPixelBuffer 的情况下创建它。
  • 苹果的示例代码中描述了一种方式:developer.apple.com/documentation/metal/…
猜你喜欢
  • 2012-06-02
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多