Dear experts, I'm working on adding UI for my cpp based path tracer renderer. I want to create metal cpp device and pass it to renderer, but also I want to use ImGui and GLFW (for window manager and input events handling). I've found solution how I can mix obj c code that requires by GLFW window setup and cpp code: https://github.com/ikryukov/MetalCppImGui
// Here is key thing for integration GLFW with Metal Cpp
// GLFW supports only obj c window handle
NSWindow *nswin = glfwGetCocoaWindow(window);
CA::MetalLayer* layer = CA::MetalLayer::layer();
layer->setDevice(device);
layer->setPixelFormat(MTL::PixelFormatBGRA8Unorm); // bridge to obj c here because NSWindow expetcs objc
CAMetalLayer* l = (__bridge CAMetalLayer*)layer;
nswin.contentView.layer = l;
nswin.contentView.wantsLayer = YES;
Is there any official way to handle event in Metal cpp without objective c support? Maybe MetalKit will have such features in future?
I recommend checking out our video Program Metal in C++ with metal-cpp which gives some pointers on using C++ and Objective-C code together.
It sounds like you are specifically referring to window events like mouse and keyboard movement? If so, then I think you are on the right track in your solution. Libraries like ImGui and GLFW will mix Objective-C code with C++ in a .mm
file to solve this language interaction. In general, you can write a C++ interface in your .hpp
file and put your implementation in a .mm
file where you can mix C++ and Objective-C. Then you use your interface with your C++ code. It's also helpful to use the Pointer to Implementation (PIMPL) pattern if you need to create a C++ class that needs to store Objective-C pointers. Please see the code below for a simple example. In your case, you may want to receive the window events in Objective-C and then forward the handling to a C++ class. One main advantage to this method is that you don't need to wrap any additional Objective-C libraries that you'd like to use.
#pragma once
// A forward declaration to the class/struct that stores the private implementation.
class PrivateImplementation;
/// A class that uses the pointer-to-implementation (PIMPL) design pattern.
class PublicClass {
public:
PublicClass();
~PublicClass();
// Other C++ member variables and functions go here.
private:
// A pointer to the implementation class that stores the Objective-C member variables.
PrivateImplementation* pImpl;
};
And use the Objective-C code in the .mm
file.
#include <Metal/Metal.h>
#include "PublicClass.hpp"
class PrivateImplementation {
// Member variables that are Objective-C objects go here.
// An example texture object.
id<MTLTexture> exampleTextureObject;
};
/// Allocates the private implementation class.
PublicClass::PublicClass() {
pImpl = new PrivateImplementation();
}
/// Deallocates the private implementation class.
PublicClass::~PublicClass() {
delete pImple;
}