Sample Code

Mixing Metal and OpenGL Rendering in a View

Draw with Metal and OpenGL in the same view using an interoperable texture.

Download

Overview

If you’re developing a new app and migrating legacy OpenGL code to Metal, interoperable textures make it easy for you to see the results live as you go.

You can render Metal or OpenGL content into either view by initializing a CVPixelBuffer that operates as an interoperable texture. By enabling both the pixel buffer’s Metal and OpenGL compatibility flags, the textures are capable of being drawn to—and presented by—either rendering technology.

If you’re working with an app you’ve already deployed, the interoperable textures give you the option of incrementally releasing updates throughout the porting process.

Draw Metal Content in an OpenGL View

When porting your app statement-by-statement, start by setting up Metal to be able to render into your app’s existing OpenGL view using a pixel format supported by both renderers:

MTLPixelFormat interopPixelFormat = MTLPixelFormatBGRA8Unorm;

Next, you create an interoperable Metal renderer by choosing a device and passing in the pixel format:

_metalDevice = MTLCreateSystemDefaultDevice();
_metalRenderer = [[AAPLMetalRenderer alloc] initWithDevice:_metalDevice
                                          colorPixelFormat:interopPixelFormat];

Create an interoperable texture that Metal can write to and OpenGL can read from:

_interopTexture = [[AAPLOpenGLMetalInteropTexture alloc] initWithMetalDevice:_metalDevice
                                                               openGLContext:_context
                                                            metalPixelFormat:interopPixelFormat
                                                                        size:AAPLInteropTextureSize];

Pass the interoperable texture to OpenGL:

[_openGLRenderer useSuppliedInteropTexture:_interopTexture.openGLTexture];

Then, draw to the interoperable texture using Metal, and have OpenGL present it to the screen:

[_metalRenderer drawToInteropTexture:_interopTexture.metalTexture];
[_openGLRenderer draw];

The result, as rendered in this sample app:

Screenshot of the app showing, in the background, a blue color filled by OpenGL, and a texture rendered on top of that using Metal.

OpenGL cleared the background with a dark gray color, and Metal renders a brick-like texture on top. Finally, OpenGL presented the result in a view.

Draw OpenGL Content in a Metal View

Draw OpenGL content into a Metal view when you’re ready to use Metal but have some legacy OpenGL code that you intend to port incrementally. First, create a Metal renderer as usual:

_metalRenderer = [[AAPLMetalRenderer alloc] initWithDevice:_view.device
                                          colorPixelFormat:_view.colorPixelFormat];

Then, create a normal OpenGL context, and an interoperable texture OpenGL can write to, and Metal can read from. The interoperate texture needs both, the Metal device, and OpenGL context:

[self createOpenGLContext];
_interopTexture = [[AAPLOpenGLMetalInteropTexture alloc] initWithMetalDevice:_view.device
                                                               openGLContext:_openGLContext
                                                            metalPixelFormat:MTLPixelFormatBGRA8Unorm_sRGB
                                                                        size:AAPLInteropTextureSize];

Create an OpenGL renderer and pass it the interoperable texture:

[self intializeOpenGLRendererWithInteropTexture:_interopTexture];

Also, pass the interoperable texture to the Metal renderer:

[_metalRenderer useSuppliedTexture:_interopTexture.metalTexture];

Draw on the interoperable texture with OpenGL, flush, and have Metal present the texture to the screen:

[_openGLRenderer draw];
glFlush();
[_metalRenderer drawToMTKView:view];

The result, as rendered in this sample app:

Screenshot of the app showing, in the background, a blue color filled by OpenGL, and a texture rendered on top of that using Metal.

OpenGL cleared the background of the interoperable texture and rendered a texture on top of that. Finally, Metal presented the interoperable texture in a view.

See Also

Sample Code

Fundamental Lessons

Learn how to develop Metal apps by following introductory lessons and guided examples.

Advanced Techniques

Learn how to implement advanced techniques by using Metal features efficiently.