I'm trying to use the official metal-cpp headers to make an entirely C++ metal app using GLFW. I don't want to write any objective-c if possible.
#define GLFW_EXPOSE_NATIVE_COCOA
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include <Metal/Metal.hpp>
#include <MetalKit/MetalKit.hpp>
#include <QuartzCore/QuartzCore.hpp>
int main() {
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow( 1280, 720, "Hello World", nullptr, nullptr);
auto nswindow = glfwGetCocoaWindow(window);
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window)) {
/* Render here */
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
I don't know if this is even possible, but my specific hurdle right now is converting the objective-c NSWindow
returned from glfwGetCocoaWindow
to an NS::Window
C++ object.
You can't get rid of Objective-C(++) completely when using GLFW.
You need a *.h
/*.m(m)
combination that adds a Metal Layer to the NSWindow.
#ifndef COCOA_BRIDGE
#define COCOA_BRIDGE
#include <metal/metal.hpp>
struct GLFWwindow;
namespace CA {
class MetalLayer;
}
namespace X {
void add_layer_to_window(GLFWwindow* window, CA::MetalLayer* layer);
}
#endif
#import "cocoa_bridge.h"
#include <GLFW/glfw3.h>
#define GLFW_EXPOSE_NATIVE_COCOA
#include <GLFW/glfw3native.h>
#import <QuartzCore/CAMetalLayer.h>
namespace X{
void add_layer_to_window(GLFWwindow* window, CA::MetalLayer* layer) {
NSWindow* cocoa_window = glfwGetCocoaWindow(window);
CAMetalLayer* native_layer = (__bridge CAMetalLayer*)layer;
[[cocoa_window contentView] setLayer:native_layer];
[native_layer setMaximumDrawableCount:2];
[[cocoa_window contentView] setWantsLayer:YES];
[[cocoa_window contentView] setNeedsLayout:YES];
}
}
auto* window = (GLFWwindow*)get_window();
layer = NS::TransferPtr(CA::MetalLayer::layer());
layer->setDevice(device.get());
layer->setFramebufferOnly(true);
layer->setPixelFormat(MTL::PixelFormat::PixelFormatBGRA8Unorm_sRGB);
add_layer_to_window(window, layer.get());
the whole rendering happens then via the layer.