MacでObjective-cを使ってMetalを初期化

最近iOsでMetalずいていたのでMacでMetalの覚書

■Step1：プロジェクト作成
---
　プロジェクト作成すると。
![スクリーンショット 2018-11-19 15.50.04.png](https://qiita-image-store.s3.amazonaws.com/0/122121/ab20c021-fe6f-2641-71d3-463d18db91ab.png)
の画面が出てきますので「Applocation」は「Cocoa App」を選択し「Next」を押してください。
![スクリーンショット 2018-11-19 15.50.26.png](https://qiita-image-store.s3.amazonaws.com/0/122121/6c87e094-14ac-8d84-306e-9186f7858aed.png)
次に「Product Name」ですが今回は「Test01」としています（これはなんでもOKです）
　言語設定「Language」は「Objective-c」を設定してください。
　あと「Use Storyboards」にチェックを忘れずに
　「Next」を押し、ディレクトリを指定して「Create」を押せばプロジェクトの作成ができます。
![スクリーンショット 2018-11-19 15.50.43.png](https://qiita-image-store.s3.amazonaws.com/0/122121/7cd3a495-3815-f9b5-10cd-300ba24ff189.png)
このような画面が出てきます。
■Step2：MetalRendererクラス作成
---
プロジェクトに「MetalRenderer.m」「MetalRenderer.h」を追加します
![スクリーンショット 2018-11-19 16.24.00.png](https://qiita-image-store.s3.amazonaws.com/0/122121/f0f83d94-9635-e925-d5e6-a19d0fd746d5.png)

```objective_c: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
```
```objective_c: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の編集
---
```objective_c: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
```
■Step4：Viewの設定
---
ストーリーボードからViewに設定をします。
![スクリーンショット 2018-11-19 16.28.01.png](https://qiita-image-store.s3.amazonaws.com/0/122121/97268d7b-b77c-130b-8c12-90560a6fe487.png)
「Main.storyboad」から「View」を選択します。
すると右側にClassを設定する所が出てきますのでそこに「MTKView」を指定してください。
■Step5：実行
---
赤い画面が現れます
![スクリーンショット 2018-11-19 16.29.35.png](https://qiita-image-store.s3.amazonaws.com/0/122121/920e3629-babf-3749-21c1-d2ff0a2e0ef9.png)