この記事は、Metal Advent Calendar2016の7日目の記事です。
これまで、MetalのGPUコンピューティングについて解説記事を書いてきました。
[iOS] MetalでGPUコンピューティング (1)
[iOS] MetalでGPUコンピューティング (2)
[iOS] MetalでGPUコンピューティング (3)
本記事では、前回に引き続きAppleが提供するサンプルコードの解説を行います。
扱うサンプルコードは、前回と同じライフゲームのアプリ、MetalGameOfLifeです。
MetalGameOfLife
今回は、GPUコンピューティングとは少々離れるのですが、サンプルコード内のMTKViewについて解説を行います。
MTKViewはMetalKitフレームワークに含まれるUIViewを継承したクラスで、比較的シンプルな方法でMetalによる描画を行うことができます。
MTLViewは、以下の3つの描画モードがあります。
- 内部のタイマーによる自動的な再描画(デフォルト)
- setNeedDisplayを呼び出すことによる描画
- 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に以下の記述があります。
self.metalView = (MTKView *)self.view;
...
self.metalView.device = MTLCreateSystemDefaultDevice();
MTLCreateSystemDefaultDevice()はMTLDeviceプロトコルに従うオブジェクトを返しますが、MTKViewのオブジェクトはMetal関連のオブジェクトを作成したりコントロールするためにこれを必要とします。
続いて、AAPLRender.m側のコードです。
MTLRenderPassDescriptor *renderPassDescriptor = self.view.currentRenderPassDescriptor;
...
[commandBuffer presentDrawable:self.view.currentDrawable];
MTLRenderPassDescriptorオブジェクトの取得と、描画領域(currentDrawable)の取得に用いています。
MTLRenderPassDescriptorはコマンドエンコーダーを生成するための、テクスチャなどのアタッチメントを格納しています。コマンドエンコーダーについては後ほど解説します。
下記はMTLViewによって呼び出されるデリゲートメソッドです。
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
//描画領域変更時の処理
}
...
- (void)drawInMTKView:(nonnull MTKView *)view
{
//描画毎の処理
}
画面の再描画が要求されるたびに、デリゲートメソッドであるdrawInMTKView:が呼ばれるか、MTKViewのサブクラスのdrawRect:メソッドが呼ばれます。これらのうち、どちらかを実装する必要があります。
今回はライフゲームのサンプルコード内におけるMTKViewの解説を行いました。
次回以降、さらに他の箇所についての解説を行なっていきます。