Как преобразовать существующую текстуру OpenGL в металлическую текстуру - PullRequest
0 голосов
/ 18 декабря 2018

Я работаю над разработкой некоторых плагинов для FxPlug для Motion и FCP X. В конечном счете, я хотел бы, чтобы они рендерились в металле, поскольку Apple осуждает OpenGL.

В настоящее время я использую CoreImage, и хотя я смог использовать функциональность CoreImage для обработки металла вне SDK FxPlug, FxPlug предоставляет мне только рамку в качестве текстуры OpenGL.Я попытался просто передать это в фильтр CoreImage, но в итоге получаю эту ошибку:

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

После небольшого исследования я обнаружил, что якобы могу использовать CVPixelBuffers дляобмениваться текстурами между ними, но после некоторой попытки написать код, использующий этот метод, я пришел к убеждению, что это было задумано как способ ЗАПИСАТЬ (например, создать с нуля) общий буфер, но неконвертировать между.Хотя это может быть неправильно, я не могу найти способ заставить существующую текстуру GL существовать в CVPixelBuffer.

TL; DR: я нашел способы получить результирующую текстуру Metal или OpenGL ОТ CVPixelBuffer,но я не могу найти способ создать CVPixelBuffer из существующей текстуры OpenGL.Мое сердце не настроено на этот метод, так как моя конечная цель - просто конвертировать из OpenGL в Metal, а затем обратно в OpenGL (в идеале эффективным способом).

Кто-нибудь еще нашел способ работать с FxPlug?с металлом?Есть ли хороший способ конвертировать текстуру OpenGL в Metal / CVPixelBuffer?

1 Ответ

0 голосов
/ 22 января 2019

Я написал FxPlug, который использует текстуры OpenGL и текстуры Metal.То, что вы ищете, это IOSurface.Это текстуры, которые можно использовать с Metal или OpenGL, хотя они имеют некоторые ограничения.Таким образом, если у вас уже есть текстура Metal или OpenGL, вы должны скопировать ее в IOSurface, чтобы использовать ее с другой системой.

Чтобы создать IOSurface, вы можете использовать CVPixelBuffer s(включив kCVPixelBufferIOSurfacePropertiesKey ) или вы можете создать его напрямую, используя класс IOSurface, определенный в <IOSurface/IOSurfaceObjC.h>.

Получив IOSurface, вы можете скопировать в него свою текстуру OpenGL, получив текстуру OpenGL из IOSurface через CGLTexImageIOSurface2D() (определено в <OpenGL/CGLIOSurface.h>).Затем вы берете эту текстуру и используете ее в качестве вспомогательной текстуры для FBO.Вы можете, например, нарисовать текстурированный квад в нем, используя в качестве текстуры ввод FxTexture.Обязательно наберите glFlush(), когда закончите!

Затем возьмите IOSurface и создайте из него MTLTexture с помощью -[MTLDevice newTextureWithDescriptor:ioSurface:plane:] (описано здесь ).Вы захотите создать вывод IOSurface для рисования, а также создать MTLTexture из него.Сделайте рендеринг вашего Металла в вывод MTLTexture.Затем возьмите вывод IOSurface и создайте из него текстуру OpenGL с помощью CGLTexImageIOSurface2D().Теперь скопируйте эту текстуру OpenGL в выходной FxTexture, используя ее в качестве основы FBO на основе текстуры или любым другим методом, который вы предпочитаете.

Как вы можете видеть, недостатком этого является то, что для каждого рендера требуется 2копирует - 1 входную информацию в IOSurface и 1 выходную IOSurface в выходную текстуру, которую дает вам приложение.Другим недостатком является то, что это, вероятно, спорный вопрос, поскольку Apple публично объявила о прекращении поддержки OpenGL и, вероятно, уже работает над решением на основе Metal.Это может быть дополнительная работа, чтобы сделать все это самостоятельно.(Хотя плюс в том, что вы можете использовать этот же код в других хост-приложениях, которые поддерживают только OpenGL.)

...