LoginSignup
6

More than 5 years have passed since last update.

posted at

updated at

Organization

【Swift2.0でMetal入門】1.Metalの初期化フェーズ

この記事は前回の解説的内容です。
入門としては1.5回目に位置します。

目的

Metalの使用用途がGameというイメージが強すぎるので、通常のアプリや表現としても使えることを探っていきます。

注意

MetalはiOS8以上の固有機能です。Metalを動かすにはA7チップ以上のデバイスが必要です。Macで開発する場合は
シュミレーターではなく、実機で確認するようにしてください。

前回のコードと確認しながら進めると分かりやすいと思います。

MetalとOpenGLの違い

MetalはOpenGLESより高速で動きます。しかしOpenGLESはクロスプラットフォームというメリットがあります。そのためOpenGLESのアプリはAndroid、Windowsなどに移植しやすいです。ちなみにSpriteKitやSceneKitはOpenGLESを利用しています。

MetalのメリットはOpenGLESより優れたパフォーマンスと、個人的にはコードの記述がスマートな所だと思います。パファーマンスが出ない場合はMetalの使用を検討しても良いと思います。

まとめるとMetalのメリットとしては

  • OpenGLESよりすぐれたパフォーマンス(CPUとGPUのメモリを共通使用するためとかとか)
  • コードの記述がスマート(私の個人的な感想です)

グラフィックスライブラリの2つのフェーズ

前回の投稿をみても、グラフィックスライブラリを使う場合、大きく2つのフェーズに分かれます。

  • 初期化フェーズ
  • 描画フェーズ

初期化フェーズ

まず初期化フェーズではグラフィックスライブラリの初期化、描画の準備を行います。
順番にみると

  • 1.GPUへのアクセス方法を用意
  • 2.CPUとGPUの連携準備
  • 3.頂点やバッファの準備
  • 4.レンダリングパイプラインを準備

で設定します。

1.GPUへのアクセス方法を用意

ここで最初にすることは、deviceを取得することです。これでプログラムを実行しているdeviceとやり取りができます。またデバイスの情報も取得できます。

let device: MTLDevice! = MTLCreateSystemDefaultDevice()

2.CPUとGPUの連携準備

グラフィックスの情報は非同期にCPUからGPUに送信されます。これはCPUでまず処理が実行され、次にGPUに転送されます。画面上の特定の1pxで考えると、CPUとGPUが同一のピクセルに対して同時に処理をすることはないです。
この処理を順番に行うためにキューを準備します。CPUはGPUに渡す情報をキューに追加していき、GPUはキューから順番に情報を抜き出し処理します。

let commandQueue: MTLCommandQueue!  = device.newCommandQueue()

3.頂点、バッファの準備

GPUへ渡したい頂点情報を準備します。スクリーン上に表示するオブジェクトを定義します。


// 頂点
let vertexArray: [Float] = [
    -1.0, 1.0, 0, 1,
    -1.0, -1.0, 0, 1,
    1.0, -1.0, 0, 1,
    -1.0, 1.0, 0, 1,
    1.0, -1.0, 0, 1,
    1.0, 1.0, 0, 1
]

ヴァッファは頂点、色、テクスチャなどあり、頂点の数だけバッファを作成します。

let vertexBuffer: MTLBuffer! = device.newBufferWithBytes( vertexArray,
    length: vertexArray.count * sizeofValue(vertexArray[0]),
    options: MTLResourceOptions.OptionCPUCacheModeDefault
)

4.レンダリングパイプラインを準備

このステップは2に分かれます。最初のフェーズでは、Shaderプログラムを用意し読み込みます。
SwiftでShaderプログラムを使う場合は、Shader Libraryに読み込む必要があります。

// Shader Library設定
let defaultLibrary = device.newDefaultLibrary()
let newVertexFunction = defaultLibrary!.newFunctionWithName("vertexShader")
let newFragmentFunction = defaultLibrary?.newFunctionWithName("fragmentShader")

次のステップではディスクリプタを作成します。
ディスクリプタに
パイプラインを初期化し画像をラスタライズしながら、フォーマットが使用するピクセルを教えてくれます。

let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction      = newVertexFunction
pipelineStateDescriptor.fragmentFunction    = newFragmentFunction     pipelineStateDescriptor.colorAttachments[0].pixelFormat = .BGRA8Unorm // 色成分の順序を設定

ディスクリプタの役目あたりは、まだ曖昧ですみません。
今回は初期化フェーズまでとします。次回は描画フェーズの解説を投稿します。

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
What you can do with signing up
6