LoginSignup
7
6

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-12-13

この記事は前回の解説的内容です。
入門としては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 // 色成分の順序を設定

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

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