MetalDay 7

[iOS]MetalでGPUコンピューティング(4) MTKView

More than 1 year has passed since last update.

この記事は、Metal Advent Calendar2016の7日目の記事です。

これまで、MetalのGPUコンピューティングについて解説記事を書いてきました。

[iOS] MetalでGPUコンピューティング (1)

[iOS] MetalでGPUコンピューティング (2)

[iOS] MetalでGPUコンピューティング (3)


本記事では、前回に引き続きAppleが提供するサンプルコードの解説を行います。

扱うサンプルコードは、前回と同じライフゲームのアプリ、MetalGameOfLifeです。

MetalGameOfLife

IMG_5933.PNG

(実行画面)

今回は、GPUコンピューティングとは少々離れるのですが、サンプルコード内のMTKViewについて解説を行います。

MTKViewはMetalKitフレームワークに含まれるUIViewを継承したクラスで、比較的シンプルな方法でMetalによる描画を行うことができます。

MTLViewは、以下の3つの描画モードがあります。


  1. 内部のタイマーによる自動的な再描画(デフォルト)

  2. setNeedDisplayを呼び出すことによる描画

  3. MTKViewのdrawメソッドによる描画


このサンプルコードでは、デフォルトである1.のモードを用いています。

前回の繰り返しになるのですが、このサンプルコードは、主に以下のファイルで構成されています。

AAPLRender.h

AAPLRender.m

AAPLViewController.h

AAPLViewController.m

Sharder.metal

このうち、AAPLRender.mには並列コンピューティング及び描画のCPU側のロジックが、Shader.metalには頂点シェーダー、フラグメントシェーダー、GPUコンピューティング用のシェーダーが書かれています。

ここからは、サンプルコード内におけるMTKViewの使用箇所を解説していきます。

StoryboardのCustum ClassにMTKViewを設定した上で、AAPLViewController.mに以下の記述があります。


AAPLViewController.m

self.metalView = (MTKView *)self.view;    

...
self.metalView.device = MTLCreateSystemDefaultDevice();

MTLCreateSystemDefaultDevice()はMTLDeviceプロトコルに従うオブジェクトを返しますが、MTKViewのオブジェクトはMetal関連のオブジェクトを作成したりコントロールするためにこれを必要とします。

続いて、AAPLRender.m側のコードです。


AAPLRender.m

MTLRenderPassDescriptor *renderPassDescriptor = self.view.currentRenderPassDescriptor;   

...
[commandBuffer presentDrawable:self.view.currentDrawable];

MTLRenderPassDescriptorオブジェクトの取得と、描画領域(currentDrawable)の取得に用いています。

MTLRenderPassDescriptorはコマンドエンコーダーを生成するための、テクスチャなどのアタッチメントを格納しています。コマンドエンコーダーについては後ほど解説します。

下記はMTLViewによって呼び出されるデリゲートメソッドです。


AAPLRender.m

- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size

//描画領域変更時の処理
}
...
- (void)drawInMTKView:(nonnull MTKView *)view
{
//描画毎の処理
}

画面の再描画が要求されるたびに、デリゲートメソッドであるdrawInMTKView:が呼ばれるか、MTKViewのサブクラスのdrawRect:メソッドが呼ばれます。これらのうち、どちらかを実装する必要があります。

今回はライフゲームのサンプルコード内におけるMTKViewの解説を行いました。

次回以降、さらに他の箇所についての解説を行なっていきます。