Skip to content

Instantly share code, notes, and snippets.

@Barakat
Last active October 14, 2023 22:36
Show Gist options
  • Save Barakat/4753c62dc5fbaf2f24df2ab295dde810 to your computer and use it in GitHub Desktop.
Save Barakat/4753c62dc5fbaf2f24df2ab295dde810 to your computer and use it in GitHub Desktop.
Minimal Objective-C++ SDL2 + Metal example
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(example)
set(CMAKE_CXX_STANDARD 11)
find_package(SDL2 REQUIRED)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_COMPILER_IS_CLANGCXX 1)
endif ()
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
endif ()
add_executable(example main.mm)
target_include_directories(example PRIVATE ${SDL2_INCLUDE_DIR})
target_link_libraries(example ${SDL2_LIBRARIES})
target_compile_options(example PRIVATE "-fobjc-arc")
set_target_properties(example PROPERTIES LINK_FLAGS "-framework Foundation -framework QuartzCore -framework Metal")
#include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h>
#import <Metal/Metal.h>
#import <MetalKit/MetalKit.h>
int
main(int argc, char** argv)
{
(void)argc;
(void)argv;
SDL_Init(SDL_INIT_VIDEO);
SDL_setenv("METAL_DEVICE_WRAPPER_TYPE", "1", 0);
auto window = SDL_CreateWindow("METAL",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
800,
600,
SDL_WINDOW_HIDDEN);
SDL_SysWMinfo window_system_info;
SDL_VERSION(&window_system_info.version);
SDL_GetWindowWMInfo(window, &window_system_info);
assert(window_system_info.subsystem == SDL_SYSWM_COCOA);
auto native_window = window_system_info.info.cocoa.window;
auto device = MTLCreateSystemDefaultDevice();
auto swap_chain = [CAMetalLayer layer];
swap_chain.device = device;
swap_chain.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
swap_chain.framebufferOnly = YES;
swap_chain.frame = native_window.frame;
native_window.contentView.layer = swap_chain;
native_window.opaque = YES;
native_window.backgroundColor = nil;
auto command_queue = [device newCommandQueue];
auto render_pass_descriptor = [MTLRenderPassDescriptor new];
auto render_pass_color_attachment_descriptor = render_pass_descriptor.colorAttachments[0];
render_pass_color_attachment_descriptor.texture = nil;
render_pass_color_attachment_descriptor.loadAction = MTLLoadActionClear;
render_pass_color_attachment_descriptor.clearColor = MTLClearColorMake(0.2, 0.58, 0.7, 1.0);
render_pass_color_attachment_descriptor.storeAction = MTLStoreActionStore;
SDL_ShowWindow(window);
for (;;)
{
SDL_Event event{};
if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
break;
}
}
auto render_surface = [swap_chain nextDrawable];
auto render_target = render_surface.texture;
render_pass_color_attachment_descriptor.texture = render_target;
auto command_buffer = [command_queue commandBuffer];
auto command_buffer_encoder = [command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor];
// ...
[command_buffer_encoder endEncoding];
[command_buffer presentDrawable:render_surface];
[command_buffer commit];
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment