LoginSignup
0
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-11-16

iOs12からOpenGLESが非推奨になってしまったので、Metalに移るための覚書

■Step1:プロジェクト作成

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

■Step2:MetalRendererクラス作成

 プロジェクトに「MetalRenderer.m」「MetalRenderer.h」を追加します
スクリーンショット 2018-11-20 16.49.52.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
#import <MetalKit/MetalKit.h>

@interface MetalRenderer : NSObject <MTKViewDelegate>

-(nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)view;

@end

■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();
    _view.backgroundColor = UIColor.blackColor;
    if(!_view.device)
    {
        NSLog(@"Metal is not supported on this device");
        self.view = [[UIView 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-16 16.36.10.png
「Main.storyboad」から「View」を選択します。
すると右側にClassを設定する所が出てきますのでそこに「MTKView」を指定してください。

■Step5:実行

 Metalをシミュレータでは実行できませんので、実機での確認をお願いします。
赤い画面が出ます

0
0
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
0
0