最近iOsでMetalずいていたのでMacでMetalの覚書
■Step1:プロジェクト作成
プロジェクト作成すると。
の画面が出てきますので「Applocation」は「Cocoa App」を選択し「Next」を押してください。
次に「Product Name」ですが今回は「Test01」としています(これはなんでもOKです)
言語設定「Language」は「Objective-c」を設定してください。
あと「Use Storyboards」にチェックを忘れずに
「Next」を押し、ディレクトリを指定して「Create」を押せばプロジェクトの作成ができます。
このような画面が出てきます。
■Step2:MetalRendererクラス作成
プロジェクトに「MetalRenderer.m」「MetalRenderer.h」を追加します
MetalRenderer.m
#import "MetalRenderer.h"
static const NSUInteger MaxBuffersInFlight = 3;
@implementation MetalRenderer
{
dispatch_semaphore_t _in_flight_semaphore;
id <MTLDevice> _device;
id <MTLCommandQueue> _command_queue;
}
-(nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)view;
{
if(self = [super init])
{
_device = view.device;
_in_flight_semaphore = dispatch_semaphore_create(MaxBuffersInFlight);
view.colorPixelFormat = MTLPixelFormatBGRA8Unorm;
_command_queue = [_device newCommandQueue];
}
return self;
}
- (void)drawInMTKView:(nonnull MTKView *)view
{
dispatch_semaphore_wait(_in_flight_semaphore, DISPATCH_TIME_FOREVER);
id <MTLCommandBuffer> command_buffer = [_command_queue commandBuffer];
__block dispatch_semaphore_t block_sema = _in_flight_semaphore;
[command_buffer addCompletedHandler:^(id<MTLCommandBuffer> buffer)
{
dispatch_semaphore_signal(block_sema);
}];
MTLRenderPassDescriptor* render_pass_descriptor = view.currentRenderPassDescriptor;
render_pass_descriptor.colorAttachments[0].loadAction=MTLLoadActionClear;
render_pass_descriptor.colorAttachments[0].storeAction=MTLStoreActionStore;
render_pass_descriptor.colorAttachments[0].clearColor=MTLClearColorMake(1.0, 0.0, 0.0, 1.0);
if(render_pass_descriptor != nil)
{
id <MTLRenderCommandEncoder> render_encoder =
[command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor];
[render_encoder endEncoding];
[command_buffer presentDrawable:view.currentDrawable];
}
[command_buffer commit];
}
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
{
}
@end
MetalRenderer.h
#ifndef MetalRenderer_h
#define MetalRenderer_h
#import <MetalKit/MetalKit.h>
@interface MetalRenderer : NSObject <MTKViewDelegate>
-(nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)view;
@end
#endif /* MetalRenderer_h */
■Step3:ViewController.mの編集
ViewController.m
#import "ViewController.h"
#import "MetalRenderer.h"
@implementation ViewController
{
MTKView *_view;
MetalRenderer *_renderer;
}
- (void)viewDidLoad {
[super viewDidLoad];
_view = (MTKView *)self.view;
_view.device = MTLCreateSystemDefaultDevice();
if(!_view.device)
{
NSLog(@"Metal is not supported on this device");
self.view = [[NSView alloc] initWithFrame:self.view.frame];
return;
}
_renderer = [[MetalRenderer alloc] initWithMetalKitView:_view];
[_renderer mtkView:_view drawableSizeWillChange:_view.bounds.size];
_view.delegate = _renderer;
}
@end