bonnie m
bonnie m

Reputation: 11

Getting the ObjectiveC reference of a C# Object (Xamarin.iOS, CAMetalLayer)

I am new to Objective C and I am trying to port my OpenGL based 3D rendering engine to Metal. In the current state, the Window creation and View controller management are in C# (based on Xamarin.iOS) and Rendering part is handled in Native ( C++ & OpenGL).

I am thinking of creating the CAMetalLayer in the ViewController in C# and rest of the Metal related rendering code in Objective C. Can anyone tell me how can I pass the reference of the CAMetalLayer instance and use it in Objective C code.

public override void ViewDidLoad()
 {
     base.ViewDidLoad();
      // Perform any additional setup after loading the view, typically from a nib.
     mtlDevice = Metal.MTLDevice.SystemDefault;
     mtlLayer = new CAMetalLayer();
            

     mtlLayer.Device = mtlDevice;
     mtlLayer.PixelFormat = MTLPixelFormat.BGRA8Unorm; 
     mtlLayer.FramebufferOnly = true;    
     mtlLayer.Frame = View.Layer.Frame;  
     View.Layer.AddSublayer(mtlLayer);  



}

How can I pass the reference of the mtlLayer which is created in C# to objective C?

Or I can create the mtlLayer in Objective C, but how do I do the View.Layer.AddSublayer()?

Upvotes: 0

Views: 99

Answers (1)

bonnie m
bonnie m

Reputation: 11

Found the answer to my own question after some reading.

From C#

  1. Pass the mtlLayer.Handle(IntPtr) to native through DllImport

     public class Engine
     {
         [DllImport("__Internal", EntryPoint = "nativeMetalInit")]
         public static extern void Init(
             IntPtr device,
             IntPtr layer);
    
     }
    
     Engine.Init(mtlDevice.Handle, mtlLayer.Handle);
    

In Native C/Cpp library

API void nativeMetalInit(void* device, void *layer)
{
    metalInit(device, layer);
}

In the Objective Cpp (.mm file)

void metalInit(void *device, void *layer)
{
    pRenderer = [[NativeRenderer alloc] init];
    [pRenderer initilalizeMetal: device andLayer:layer];
}

- (void)initilalizeMetal: (void*) pDevice andLayer: (void*) pLayer 
{
    self.mtlLayer = (__bridge CAMetalLayer*) pLayer;
    self.mtlDevice = (__bridge id<MTLDevice>)pDevice;
}

Upvotes: 0

Related Questions