4

I am trying to learn metal and since I am already familiar with C++, I am trying to do it using metal-cpp. I am not an experienced macOS developer but I have worked in Xcode in the past in projects using OpenGL and C++ as the main language.

My question is how to set up a project in C++ and use Metal to render to a window or view. I have found some tutorials on how to do this in Swift or Objective-C but nothing in C++. A couple of years ago, I remember doing something similar with OpenGL and if I recall correctly, the view had to be set in Objective-C and then pass the OpenGL context to C++.

Would this be a good approach for this case (set up the view in Swift/Obj-C and then pass a device to C++)? I am also a bit lost with what type of project or other files I would need to do this (i.e. storyboards, etc.). As of now I just have a command-line tool project with the Foundation, Mmetal, MetalKit and QuartzCore frameworks linked; plus metal-cpp linked and compiling too.

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
dandov
  • 41
  • 2

1 Answers1

5

I was doing various C++ projects on Mac and I personally would stick to using cmake instead of XCode, especially that I may generate XCode project out of the cmake one (but usually I use Ninja Multi-Config generators). The following example is a minimal cmake project which sets up metal-cpp unpacked to the main directory (containing the CMakeLists.txt file).

cmake_minimum_required (VERSION 3.20)
project (metal_cpp_rocks)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")

find_library(APPLE_FWK_FOUNDATION Foundation REQUIRED)
find_library(APPLE_FWK_QUARTZ_CORE QuartzCore REQUIRED)
find_library(APPLE_FWK_METAL Metal REQUIRED)

add_executable(metal_cpp_rocks
  main.cpp
)

target_include_directories(metal_cpp_rocks
  SYSTEM PUBLIC ${CMAKE_SOURCE_DIR}/metal-cpp
)

target_link_libraries(metal_cpp_rocks
  ${APPLE_FWK_FOUNDATION}
  ${APPLE_FWK_QUARTZ_CORE}
  ${APPLE_FWK_METAL}
)

and the minimal main.cpp

#define NS_PRIVATE_IMPLEMENTATION
#define CA_PRIVATE_IMPLEMENTATION
#define MTL_PRIVATE_IMPLEMENTATION

#include <Foundation/Foundation.hpp>
#include <Metal/Metal.hpp>
#include <QuartzCore/QuartzCore.hpp>

int main()
{
  MTL::Device* device = MTL::CreateSystemDefaultDevice();
  device->release();
  return 0;
}

Building and running (being in the main directory):

cmake -S . -B build -G "Ninja Multi-Config"
cmake --build build --config Release
./build/Release/metal_cpp_rocks

An example of how to generate an XCode project from the cmake one in order to use XCode as the IDE during development:

cmake -S . -B build_xcode -G "Xcode"

Now open the generated build_xcode/metal_cpp_rocks.xcodeproj from XCode and do everything in a usual way, but remember not to change the project itself in XCode - modify the cmake project and regenerate the XCode project instead.

tomaszmi
  • 443
  • 2
  • 6
  • This is great thanks! Do you know how to set up a window or view and use the device to render to it? – dandov Jan 23 '22 at 08:56
  • I run into `fatal error: 'Foundation/Foundation.hpp' file not found` when trying this. – Chris Seymour Mar 02 '22 at 17:56
  • @ChrisSeymour you need to download metal-cpp from Apple's developer website. https://developer.apple.com/metal/cpp/ – grafo Apr 06 '22 at 06:39
  • @grafo once downloaded how do you get it to link and compile? I've downloaded and unzipped it but where do i put it so the system finds it? – Nick Mar 28 '23 at 03:11