Last active
September 9, 2021 10:53
-
-
Save slime73/12284a8299be857d2581 to your computer and use it in GitHub Desktop.
SDL + Metal example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This software is in the public domain. Where that dedication is not recognized, | |
* you are granted a perpetual, irrevokable license to copy and modify this file | |
* as you see fit. | |
* | |
* Requires SDL 2.0.4. | |
* Devices that do not support Metal are not handled currently. | |
**/ | |
#import <UIKit/UIKit.h> | |
#import <Metal/Metal.h> | |
#import <QuartzCore/CAMetalLayer.h> | |
#include <SDL.h> | |
#include <SDL_syswm.h> | |
@interface MetalView : UIView | |
@property (nonatomic) CAMetalLayer *metalLayer; | |
@end | |
@implementation MetalView | |
+ (Class)layerClass | |
{ | |
return [CAMetalLayer class]; | |
} | |
- (instancetype)initWithFrame:(CGRect)frame | |
{ | |
if ((self = [super initWithFrame:frame])) { | |
/* Resize properly when rotated. */ | |
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; | |
/* Use the screen's native scale (retina resolution, when available.) */ | |
self.contentScaleFactor = [UIScreen mainScreen].nativeScale; | |
_metalLayer = (CAMetalLayer *) self.layer; | |
_metalLayer.opaque = YES; | |
_metalLayer.device = MTLCreateSystemDefaultDevice(); | |
[self updateDrawableSize]; | |
} | |
return self; | |
} | |
/* Set the size of the metal drawables when the view is resized. */ | |
- (void)layoutSubviews | |
{ | |
[super layoutSubviews]; | |
[self updateDrawableSize]; | |
} | |
- (void)updateDrawableSize | |
{ | |
CGSize size = self.bounds.size; | |
size.width *= self.contentScaleFactor; | |
size.height *= self.contentScaleFactor; | |
_metalLayer.drawableSize = size; | |
} | |
@end | |
int main(int argc, char *argv[]) | |
{ | |
SDL_InitSubSystem(SDL_INIT_VIDEO); | |
SDL_Window *window = SDL_CreateWindow("", 0, 0, 480, 320, SDL_WINDOW_RESIZABLE); | |
SDL_SysWMinfo info; | |
SDL_VERSION(&info.version); | |
SDL_GetWindowWMInfo(window, &info); | |
/** | |
* As of SDL 2.0.4, a view and view controller is associated with a | |
* window as soon as the window is created. In previous SDL versions | |
* that didn't happen until SDL_GL_CreateContext(window) was called. | |
**/ | |
UIView *sdlview = info.info.uikit.window.rootViewController.view; | |
MetalView *metalview = [[MetalView alloc] initWithFrame:sdlview.frame]; | |
[sdlview addSubview:metalview]; | |
MTLRenderPassDescriptor *renderdesc = [MTLRenderPassDescriptor renderPassDescriptor]; | |
MTLRenderPassColorAttachmentDescriptor *colorattachment = renderdesc.colorAttachments[0]; | |
/* Clear to a red-orange color when beginning the render pass. */ | |
colorattachment.clearColor = MTLClearColorMake(1.0, 0.3, 0.0, 1.0); | |
colorattachment.loadAction = MTLLoadActionClear; | |
colorattachment.storeAction = MTLStoreActionStore; | |
id <MTLCommandQueue> queue = [metalview.metalLayer.device newCommandQueue]; | |
while (1) { | |
SDL_Event e; | |
while (SDL_PollEvent(&e)) { | |
/* Handle SDL events. */ | |
} | |
@autoreleasepool { | |
id <MTLCommandBuffer> cmdbuf = [queue commandBuffer]; | |
id <CAMetalDrawable> drawable = [metalview.metalLayer nextDrawable]; | |
colorattachment.texture = drawable.texture; | |
/* The drawable's texture is cleared to the specified color here. */ | |
id <MTLRenderCommandEncoder> encoder = [cmdbuf renderCommandEncoderWithDescriptor:renderdesc]; | |
[encoder endEncoding]; | |
[cmdbuf presentDrawable:drawable]; | |
[cmdbuf commit]; | |
} | |
} | |
[metalview removeFromSuperview]; | |
SDL_DestroyWindow(window); | |
SDL_QuitSubSystem(SDL_INIT_VIDEO); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm doing something similar to this. I've noticed my
nextDrawable
call does not change size when I rotate the device; the texture I get from the CAMetalDrawable has a constant width and height. Is that why you addedupdateDrawableSize
inlayoutSubviews
?