View-base Application で OpenGL を使う
iOSの開発してて View-base Application で作成したんだけど、一部だけ 3D 処理やんなきゃいけなくなったのでメモ。
iOS で 3D 処理やる場合は大まかに2通り
- CALayer で擬似的に 3D っぽく見せる
- OpenGL 使う
一つ目の CALayer
- UIView なんかをなんちゃらtranslateとかrotateとかっていう CALayer まわりの API を使う。
- 簡単な3Dの処理を書くのは楽。
- 複雑な処理はあまり向かない。
二つ目の OpenGL は言うまでもなく、
- 複雑な描画処理をしてくれるライブラリ。
- ゴリゴリ回転したりもりもりズームしたりとかをやってくれる。
- UIView の処理と比べるとコーディングするには敷居が高い
- 表示しない画像とかを事前に計算して処理を省いたりしてるらしく高速。
通常、OpenGL 使う場合は OpenGL ES テンプレートだったり、OpenGL Game テンプレートだったりを使う。だけど、View-based Application テンプレートを使っていて、一部で OpenGL を利用する方法がわからなかったので調べてみた。
結論から言うと、必要なフレームワークをインポートして、OpenGL の処理をした UIView をビューに追加すればいいだけ。
・・・というだけだと、味気もないし、自分がサイト回って調べてわかんなかったのと一緒なので、もう少し詳しく書く。
手順的は以下
- OpenGL のテンプレートを作成する
- View-base Application のテンプレートを作成する
- View-base Application に OpenGL のテンプレートから作成された EAGLView をコピーする(この時点でOpenGLのテンプレートは削除してもいい)
- OpenGLES.framework と QuartzCore.framework をインポートする
- EAGLView とそれを表示するための UIView まわりをちょっといじる
こんな感じで View-base Application の一部のビューで OpenGL を利用することができるようになる。
手順を追っていくと、まずは OpenGL と View-base Application のプロジェクト新規作成。これに関しては特に言及する必要はないと思う。便宜的にそれぞれ FooOpenGL プロジェクトと、BarViewbase プロジェクトとする。
次にEAGLViewのコピー。
%FooOpenGL%/Classes 以下に、
- EAGLView.h
- EAGLView.m
が生成されていると思う。これがOpenGLの処理が施されたUIViewになるので、こいつを
%BarViewbase%/Classes 以下にコピーする。ターミナルで処理するならこんな感じ。
% cd BarViewbase/Classes % cp -pR ../../FooOpenGL/Classes/EAGLView* ./
ちなみにEAGLって、Embedded Apple GL の略らしい
次はフレームワークのインポート。
Xcode でBarViewbaseのプロジェクトを開き、左側にあるFrameworksを右クリック。追加→既存のフレームワークを選び、
- OpenGLES.frameworks
- QuartzCore.frameworks
を選択する。
最後に、ソースコードをいじる。これが一番はまった。
まずはESGLView.mを編集する。
初期化メソッドを initWithCoder:(NSCoder*)coder ではなく、initWithFrame:(CGRect)frame にする。initWithCoder は xib に登録されたものから呼び出されたときに処理されるものらしい。このへんはまだよくわからない。
- (id)initWithCoder:(NSCoder*)coder { self = [super initWithCoder:coder]; //.....以降はそのままでよい }
こんな感じ↓
- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; //.....以降はそのままでよい }
あとは、BarViewbaseViewController.m の loadView あたりで、この EAGLView を生成して、addSubview してあげればいい。その他のOpenGLの処理については FooOpenGLViewController.m を参考にして足りない処理をポチポチ書いていけばきっと動くはず。