iOsでSwiftを使ってMetalを初期化

iOs12からOpenGLESが非推奨になってしまったので、Metalに移るための覚書
---
■Step1：プロジェクト作成
---
プロジェクト作成すると。
![スクリーンショット 2018-11-16 19.31.16.png](https://qiita-image-store.s3.amazonaws.com/0/122121/46424c26-8cd6-4893-fca3-e5fab23ba280.png)
の画面が出てきますので「Applocation」は「Single View App」を選択し「Next」を押してください。
![スクリーンショット 2018-11-16 19.31.33.png](https://qiita-image-store.s3.amazonaws.com/0/122121/c63477c0-9960-7f6d-4ae2-858ac45a18ab.png)
次に「Product Name」ですが今回は「Test01」としています（これはなんでもOKです）
　言語設定「Language」は「Swift」を設定してください。
　「Next」を押し、ディレクトリを指定して「Create」を押せばプロジェクトの作成ができます。
![スクリーンショット 2018-11-16 19.31.51.png](https://qiita-image-store.s3.amazonaws.com/0/122121/0541a119-0518-b6a9-64d4-ec7f808f28f7.png)
このような画面が出てきます。
■Step2：MetalRendererクラス作成
---
プロジェクトに「MetalRenderer.swift」を追加します
![スクリーンショット 2018-11-16 19.33.33.png](https://qiita-image-store.s3.amazonaws.com/0/122121/37f9d086-afc2-eff9-7cd5-de6702388a48.png)

```swift:MetalRenderer.swift
import MetalKit

let maxBuffersInFlight = 3

class MetalRenderer: NSObject, MTKViewDelegate {
    let _device: MTLDevice
    let _command_queue: MTLCommandQueue
    let _in_flight_semaphore = DispatchSemaphore(value: maxBuffersInFlight)
    
    init?(metalKitView: MTKView) {
        _device = metalKitView.device!
        guard let queue = _device.makeCommandQueue() else { return nil }
        _command_queue = queue
        
        metalKitView.colorPixelFormat = MTLPixelFormat.bgra8Unorm;
        
        super.init()
    }
    
    func draw(in view: MTKView) {
        _ = _in_flight_semaphore.wait(timeout: DispatchTime.distantFuture)
        if let command_buffer = _command_queue.makeCommandBuffer() {
            
            let semaphore = _in_flight_semaphore
            command_buffer.addCompletedHandler { (_ command_buffer)-> Swift.Void in
                semaphore.signal()
            }
            let render_pass_descriptor = view.currentRenderPassDescriptor
            render_pass_descriptor?.colorAttachments[0].loadAction=MTLLoadAction.clear
            render_pass_descriptor?.colorAttachments[0].storeAction=MTLStoreAction.store
            render_pass_descriptor?.colorAttachments[0].clearColor=MTLClearColorMake(1.0, 0.0, 0.0, 1.0)
            
            if let render_pass_descriptor = render_pass_descriptor, let render_encoder = command_buffer.makeRenderCommandEncoder(descriptor: render_pass_descriptor) {
                render_encoder.endEncoding()
                if let drawable = view.currentDrawable {
                    command_buffer.present(drawable)
                }
            }
            command_buffer.commit()
        }
    }
    
    func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
    }
}
```
■Step3：ViewControllerクラスの編集
---
ViewControllerを編集し、MetalRendererと紐付けます

```swift:ViewController.swift
import UIKit
import MetalKit

class ViewController: UIViewController {
    var renderer: MetalRenderer!
    var mtkView: MTKView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        guard let mtkView = view as? MTKView else {
            print("View of Gameview controller is not an MTKView")
            return
        }
        
        // Select the device to render with.  We choose the default device
        guard let defaultDevice = MTLCreateSystemDefaultDevice() else {
            print("Metal is not supported")
            return
        }
        
        mtkView.device = defaultDevice
        mtkView.backgroundColor = UIColor.black
        
        guard let newRenderer = MetalRenderer(metalKitView: mtkView) else {
            print("Renderer cannot be initialized")
            return
        }
        
        renderer = newRenderer
        
        renderer.mtkView(mtkView, drawableSizeWillChange: mtkView.drawableSize)
        
        mtkView.delegate = renderer
    }
}

```
■Step4：Viewの設定
---
![スクリーンショット 2018-11-16 19.36.51.png](https://qiita-image-store.s3.amazonaws.com/0/122121/ff91965d-7c92-104e-30bc-32f3dafb02d2.png)
「Main.storyboad」から「View」を選択します。
すると右側にClassを設定する所が出てきますのでそこに「MTKView」を指定してください。

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