如何将现有OpenGL纹理转换为金属纹理

如何将现有OpenGL纹理转换为金属纹理,opengl,metal,core-image,cvpixelbuffer,Opengl,Metal,Core Image,Cvpixelbuffer,我正在为Motion和FCP X开发一些FxPlug插件。最终,我想让它们用金属渲染,因为苹果不喜欢OpenGL 我目前正在使用CoreImage,虽然我已经能够使用CoreImage功能在FxPlug SDK之外进行金属处理,但FxPlug仅将框架作为OpenGL纹理提供给我。我尝试将其传递到CoreImage过滤器,但最终得到以下错误: Cannot render image (with an input GL texture) using a metal-DG context. 经过一段

我正在为Motion和FCP X开发一些FxPlug插件。最终,我想让它们用金属渲染,因为苹果不喜欢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获得金属或OpenGL纹理的方法,但是我找不到从现有OpenGL纹理创建CVPixelBuffer的方法。我的心并没有放在这个方法上,因为我的最终目标是简单地从OpenGL转换到Metal,然后再回到OpenGL(理想情况下是以一种高效的方式)


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

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

要创建
IOSurface
,可以使用
CVPixelBuffer
s(包括),也可以使用
中定义的
IOSurface
类直接创建一个

拥有
IOSurface
后,可以通过
CGLTexImageIOSurface2D()
(在
中定义)从
IOSurface
获取OpenGL纹理,将OpenGL纹理复制到该纹理中。然后获取该纹理并将其用作FBO的背景纹理。例如,可以使用输入
fxture
作为纹理,在其中绘制一个带纹理的四边形。确保完成后调用
glFlush()

接下来获取
IOSurface
并通过
-[MTLDevice newTextureWithDescriptor:IOSurface:plane://code>从中创建
MTLTexture
(已描述)。您将需要创建一个输出
IOSurface
以进行绘制,并从中创建一个
MTLTexture
。在输出中执行金属渲染
MTLTexture
。接下来,获取输出
IOSurface
,并通过
CGLTexImageIOSurface2D()
从中创建OpenGL纹理。现在,将OpenGL纹理复制到输出FxTexture中,可以将其用作纹理支持FBO的背景,也可以使用您喜欢的任何其他方法


正如您所看到的,这种方法的缺点是每次渲染都需要2个副本—1个输入到
IOSurface
中,1个输出到应用程序提供的输出纹理中。另一个缺点是,这可能是毫无意义的,因为苹果已经公开宣布他们将终止对OpenGL的支持,他们可能已经在开发基于金属的解决方案。自己做可能是额外的工作。(虽然好处是,您可以在其他仅支持OpenGL的主机应用程序中使用相同的代码。)

您可以创建共享纹理,并使用OpenGL从FxPlug提供的OpenGL纹理复制到该共享纹理,使用Metal对共享纹理执行任何其他操作,然后使用OpenGL将其复制回FxPlug提供的纹理。我想我的问题是我不知道如何将其复制到共享纹理。您有任何示例代码吗?FxTexture提供
(GLuint)textureId
(盂)目标
并且我没有发现任何方法可以利用这两种方法复制到CVPixelBuffer。我假设从主机应用程序提供的FxTexture开始,这将涉及到您所说的将纹理复制到iSurface。在这种情况下,是否需要使用CVPixelBuffer?我想知道的另一件事是,纹理复制是否有任何性能损害,或者金属整体是否弥补了这一点?是的,您需要复制发送到您的
-renderOutput:withInput:withInfo:
方法的
inputImage
。它将涉及使用
IOSurface
,如果需要,您可以通过
CVPixelBuffer
创建它,但您也可以在不使用
CVPixelBuffer
的情况下创建它