Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2022 Graphics & Games

WWDC22 · 27 min · Graphics & Games

Program Metal in C++ with metal-cpp

Your C++ games and apps can now tap into the power of Metal. We’ll show you how metal-cpp helps you bridge your C++ code to Metal, explore how each manages object lifecycles, and demonstrate utilities that can help these language cooperate in your app. We’ll also share best practices for designing app architecture to elegantly integrate Objective-C and C++ together.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 9 snippets

Draw a single triangle in C++ cpp · at 3:10 ↗
MTL::CommandBuffer* pCmd = _pCommandQueue->commandBuffer();
MTL::RenderCommandEncoder* pEnc = pCmd->renderCommandEncoder( pRpd );
pEnc->setRenderPipelineState( _pPSO );
pEnc->drawPrimitives( MTL::PrimitiveTypeTriangle, 
                      NS::UInteger(0), 
                      NS::UInteger(3));
pEnc->endEncoding();
pCmd->presentDrawable( pView->currentDrawable() );
pCmd->commit();
Draw a single triangle in Objective-C objectivec · at 3:27 ↗
id<MTLCommandBuffer> cmd = [_commandQueue commandBuffer];
id<MTLRenderCommandEncoder> enc = [cmd renderCommandEncoderWithDescriptor:pRpd];
[enc setRenderPipelineState:_pPSO];
[enc drawPrimitives:MTLPrimitiveTypeTriangle 
        vertexStart:0 
        vertexCount:3];
[enc endEncoding];
[cmd presentDrawable:view.currentDrawable];
[cmd commit];
Generate the implementation cpp · at 6:10 ↗
#define NS_PRIVATE_IMPLEMENTATION
#define CA_PRIVATE_IMPLEMENTATION
#define MTL_PRIVATE_IMPLEMENTATION

#include <Foundation/Foundation.hpp>
#include <Metal/Metal.hpp>
#include <QuartzCore/QuartzCore.hpp>
How to use autoreleased objects and AutoreleasePool cpp · at 11:46 ↗
NS::AutoreleasePool* pPool = NS::AutoreleasePool::alloc()->init();
MTL::CommandBuffer* pCmd = _pCommandQueue->commandBuffer();
MTL::RenderPassDescriptor* pRpd = pView->currentRenderPassDescriptor();
MTL::RenderCommandEncoder* pEnc = pCmd->renderCommandEncoder( pRpd );
pEnc->endEncoding();
pCmd->presentDrawable( pView->currentDrawable() );
pCmd->commit();
pPool->release();
How NS::TransferPtr works cpp · at 11:47 ↗
{
   auto ptr = NS::TransferPtr( pMRR );
   // Do something with ptr 
   . . . 
}
How NS::RetainPtr works cpp · at 17:19 ↗
{
   auto ptr = NS::RetainPtr( pMRR );
   // Do something with ptr 
   . . . 
}
Create an adapter class calling C++ from Objective-C files objectivec · at 20:43 ↗
@interface AAPLRendererAdapter () 
{
    AAPLRenderer* _pRenderer;
}
@end

@implementation AAPLRendererAdapter
- (void)drawInMTKView:(MTKView *)pMtkView
{
    _pRenderer->draw((__bridge MTK::View*)pMtkView);
}

@end
Create an adapter class calling Objective-C from C++ files cpp · at 21:49 ↗
CA::MetalDrawable* AAPLViewAdapter::currentDrawable() const
{
    return (__bridge CA::MetalDrawable*)[(__bridge MTKView *)m_pMTKView currentDrawable];
}

MTL::Texture* AAPLViewAdapter::depthStencilTexture() const
{
    return (__bridge MTL::Texture*)[(__bridge MTKView *)m_pMTKView depthStencilTexture];
}
Cast between Objective-C and C++ objects and transfer ownership cpp · at 24:59 ↗
MTL::Texture* newTextureFromCatalog( MTL::Device* pDevice, const char* name,   
                                     MTL::StorageMode storageMode, MTL::TextureUsage usage )
{
    NSDictionary<MTKTextureLoaderOption, id>* options = @{
            MTKTextureLoaderOptionTextureStorageMode : @( (MTLStorageMode)storageMode ),
            MTKTextureLoaderOptionTextureUsage : @( (MTLTextureUsage)usage )
    };

    MTKTextureLoader* textureLoader = [[MTKTextureLoader alloc] 
                                        initWithDevice:(__bridge id<MTLDevice>)pDevice];
    
    NSError* __autoreleasing err = nil;
    id< MTLTexture > texture = [textureLoader 
                        newTextureWithName:[NSString stringWithUTF8String:name] 
                               scaleFactor:1 
                                            bundle:nil 
                                           options:options 
                                             error:&err];

    return (__bridge_retained MTL::Texture*)texture;
}

Resources