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の解説を行いました。
次回以降、さらに他の箇所についての解説を行なっていきます。