-
-
Save gcatlin/b89e0efed78dd91364609ca4095da346 to your computer and use it in GitHub Desktop.
// | |
// cc sdl-metal-example.m `sdl2-config --cflags --libs` -framework Metal -framework QuartzCore && ./a.out | |
// | |
#include <SDL.h> | |
#import <Metal/Metal.h> | |
#import <QuartzCore/CAMetalLayer.h> | |
int main (int argc, char *args[]) | |
{ | |
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal"); | |
SDL_InitSubSystem(SDL_INIT_VIDEO); | |
SDL_Window *window = SDL_CreateWindow("SDL Metal", -1, -1, 640, 480, SDL_WINDOW_ALLOW_HIGHDPI); | |
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC); | |
const CAMetalLayer *swapchain = (__bridge CAMetalLayer *)SDL_RenderGetMetalLayer(renderer); | |
const id<MTLDevice> gpu = swapchain.device; | |
const id<MTLCommandQueue> queue = [gpu newCommandQueue]; | |
MTLClearColor color = MTLClearColorMake(0, 0, 0, 1); | |
bool quit = false; | |
SDL_Event e; | |
while (!quit) { | |
while (SDL_PollEvent(&e) != 0) { | |
switch (e.type) { | |
case SDL_QUIT: quit = true; break; | |
} | |
} | |
@autoreleasepool { | |
id<CAMetalDrawable> surface = [swapchain nextDrawable]; | |
color.red = (color.red > 1.0) ? 0 : color.red + 0.01; | |
MTLRenderPassDescriptor *pass = [MTLRenderPassDescriptor renderPassDescriptor]; | |
pass.colorAttachments[0].clearColor = color; | |
pass.colorAttachments[0].loadAction = MTLLoadActionClear; | |
pass.colorAttachments[0].storeAction = MTLStoreActionStore; | |
pass.colorAttachments[0].texture = surface.texture; | |
id<MTLCommandBuffer> buffer = [queue commandBuffer]; | |
id<MTLRenderCommandEncoder> encoder = [buffer renderCommandEncoderWithDescriptor:pass]; | |
[encoder endEncoding]; | |
[buffer presentDrawable:surface]; | |
[buffer commit]; | |
} | |
} | |
SDL_DestroyRenderer(renderer); | |
SDL_DestroyWindow(window); | |
SDL_Quit(); | |
return 0; | |
} |
It does not work :( All I get is a black screen. Please help!
For Reak45, this code is meant to draw a black screen or very dark red. Change the clear colour in the main function to white or something bright, and remove the colour.red line in the render loop, then report your results.
For anyone who is stuck here with a black screen, you need to remove the "SDL_DestroyRenderer(renderer);" on line 17. This function in SDL destroys the View as well as the renderer which will prevent you from having anything draw to the screen. SDL_RenderGetMetalLayer will flush all the buffers before returning so there shouldn't be any conflicts.
I haven't tested on iOS, I'm guessing perhaps the UIKit based renderer on iOS behaves differently hence the author adding the destroy?
@slightlybeige thanks for figuring out the issue. It used to work as is -- I'm not sure what changed, maybe something in SDL. I moved SDL_DestroyRenderer
below the loop and updated the gist.
Try this: https://github.com/ScrimpyCat/Metal-Examples