メリークリスマス!!
iOS Advent calendarに参加してまして、24日クリスマスイブの日の記事になります。
いままで23個の記事が出てきていますが、自分が興味があった & 被らなかった のでネタは GLKit にしました。
勉強しながらなので薄い内容ですが、ご了承ください。
openGLを使って遊んだりしてたけど、iPhoneでopenGLいじろうとしたらopenGL ES 2.0でなんかいろいろ違うじゃーんという思いを胸に、
勉強していきたいと思います。
記事の流れはこんな感じです。
- ・openGL と openGL ES 2.0
- ・GLKitとは
- ・GLKitのテンプレさわってみる
openGL と openGL ES 2.0
まずはopenGLとopenGL ES 2.0の違い
- openGL ES 2.0では固定機能シェーダを完全に廃止
- glVertexPointer, glNormalPointer などの頂点系の削除
- glPushMatrix, glPopMatrix などのマトリックス系の削除
- glLight〜 などのライティング系の削除
- プログラマブルシェーダのみの実装。
- バーテックスシェーダ, フラグメントシェーダ などのシェーダを使う
などなど。
ここ を参考に。
今までopenGLの勉強したり遊んだりする場合は、固定機能シェーダを使ってました。
GLSLもすこし勉強しているものの、まだ全然使えていないので固定機能シェーダが使えずプログラマブルシェーダだけでやっていく
openGL ES 2.0 は僕には敷居が高いです。。
そんなとき、
GLKit の出番!ということですね。
shader書かかず、openGL ES 2.0でopenGL的なことができるクラスが用意されているみたいです。
GLKit について
iOS 5で追加されたopenGLのフレームワークで、openGL ES 2.0を使いやすくしてくれます。
リファレンスより(google翻訳使いました)
openGL ES 2.0 アプリケーションを作成するのに必要な労力や、
既存の openGL ES 1.1 アプリケーションを openGL ES 2.0 に移植するための労力を減らすためのライブラリを提供します。
主な機能
- Texture loading : テクスチャーの扱いを簡単にしてくれる
- Math libraries : 最適化されたベクトル、行列の関数が用意されている
- Views and View Controllers : openGL ESのレンダリング、ループの実装を提供してくれる
- Effects : 必要なシェーダの実装をやってくれる
Effects機能のGLKBaseEffectでライティングやマトリックス系の処理やってくれます。
他にもopenGL的な書き方ができるのとGLU系の関数と似たものが用意されていたりします。
こちら で詳しく説明されているので、ここにぐわーと書いたの読むより、そちらを読んだ方が深く理解できるかと思います。
GLKitのテンプレさわってみる
とりあえず最低限の使い方を理解したいので、テンプレート触ってみます。
GLKitの機能を使っているものと、shaderを使っているものの2つ分記述してあるみたいなので、GLKitの部分だけを見ていきます。
最初は立方体が2つぐるぐる回ってますが、シンプルにしていって最終的にはこんな感じに。
// - (void)viewDidLoad
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
初期化と、指定したバージョンの OpenGL ES レンダリングAPIを割り当て。
// - (void)viewDidLoad
GLKView * view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
GLKitの準備。
// - (void)setupGL
[EAGLContext setCurrentContext:self.context];
self.effect = [[GLKBaseEffect alloc] init];
self.effect.light0.enabled = GL_TRUE;
self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
最初に現在のレンダリングスレッドをセット。
次にGLKBaseEffectクラスのeffect変数にライティングを設定しています。
openGLでは8つの光源が設定できましたが、GLKBaseEffect.light* は0, 1, 2の3つしかないっぽいです。
ていうかopenGL ESはもともと3つしかないのかな?
エフェクトの初期化を抜けば、2行でライティングの設定ができて楽です。
その後はVBOの設定をしているみたいです。
// - (void)tearDownGL
[EAGLContext setCurrentContext:self.context];
glDeleteBuffers(1, &_vertexBuffer);
self.effect = nil;
viewDidUnloadではtearDownGL関数を呼んでいます。
後始末。
// - (void)update
/**
* PROJECTION
*/
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 1.0f, 100.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
/**
* MODEL VIEW
*/
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -3.0f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
self.effect.transform.modelviewMatrix = modelViewMatrix;
更新用のデリゲートメソッド
本来はglkViewControllerUpdateだけど、 GLKViewControllerのサブクラスだからupdateを呼べばいい?(たぶん)
まずはopenGLでいうところの
glMatrixMode(GL_PROJECTION); 的な部分の記述。
GLKMatrix4MakePerspectiveではgluPerspectiveとほぼほぼ同じようにかけます。GLU系が使えないけど代替の機能があるので助かります。
最後にeffect.transform.projectionMatrixに代入。
次にopenGLでいうところの
glMatrixMode(GL_MODELVIEW); 的な部分の記述。
GLKMatrix4MakeTranslationでマトリックス作りつつtranslationの設定。glTranslatedてきな感じ。
あとは必要な設定をしてeffect.transform.modelviewMatrixに代入。
glTranslated, glRotate, glScaleっぽい設定ができます。
テンプレではGLKMatrix4Multiplyを使って2つのマトリックを掛け合わせたりしてるみたいですが、
とりあえずはシンプルに理解したいので、そこはカット。
最後にテンプレではアニメーション用の_rotationの値を更新してます。
//- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 36);
描画用のデリゲートメソッド
prepareToDrawメソッドで エフェクト使うよ というのを定義して、
その後描画してます。
まとめ
いまはopenGLにすごく興味があるので、GLKitを勉強してみました。
GLKitがあればシェーダの知識がなくても使うことができて便利なので、
アプリにちょっとだけopenGL使いたいってなったときにはこれから使っていけそうです。
ただ個人的にはやっぱりシェーダーをしっかり覚えていきたいので、がっつり使って何か作るという機会はなさそうです。
ゲームっぽいの作ろう!ってなってもきっとcocos2d使うと思いますし。
クリスマスが爆発する何かを作る予定でしたが、時間がなくて断念。
勉強しながらの薄い内容で申し訳なかったですが、みなさんよいクリスマスイブを〜!!
間違いなどのご指摘あれば @_azzip まで連絡ください。
参考
・http://developer.apple.com/library/ios/#documentation/GLkit/Reference/GLKit_Collection/_index.html
・http://nantekottai.com/2011/10/13/opengl-game-template/
・http://nantekottai.com/2011/10/25/glkit-basics/
・http://d.hatena.ne.jp/nakamura001/20111117/1321545530
・http://monsho.blog63.fc2.com/blog-category-5.html
・http://d.hatena.ne.jp/ntaku/20090610/1244619913
・http://www.asahi-net.or.jp/~yw3t-trns/opengl/opengles/index.htm