LoginSignup
1
1

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-11-19

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

■Step1:プロジェクト作成

 プロジェクト作成すると。
スクリーンショット 2018-11-19 15.50.04.png
の画面が出てきますので「Applocation」は「Cocoa App」を選択し「Next」を押してください。
スクリーンショット 2018-11-19 15.50.26.png
次に「Product Name」ですが今回は「Test01」としています(これはなんでもOKです)
 言語設定「Language」は「Objective-c」を設定してください。
 あと「Use Storyboards」にチェックを忘れずに
 「Next」を押し、ディレクトリを指定して「Create」を押せばプロジェクトの作成ができます。
スクリーンショット 2018-11-19 15.50.43.png
このような画面が出てきます。

■Step2:MetalRendererクラス作成

プロジェクトに「MetalRenderer.m」「MetalRenderer.h」を追加します
スクリーンショット 2018-11-19 16.24.00.png

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

■Step4:Viewの設定

ストーリーボードからViewに設定をします。
スクリーンショット 2018-11-19 16.28.01.png
「Main.storyboad」から「View」を選択します。
すると右側にClassを設定する所が出てきますのでそこに「MTKView」を指定してください。

■Step5:実行

赤い画面が現れます
スクリーンショット 2018-11-19 16.29.35.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1