ただいま勉強中です。少し間違った情報が混じっても許して下さい。
- iPhone3G、iPod touchの第2世代まではOpenGL ES1のみが使える
- iPhone3GS/4 , iPod touch第3世代は OpenGL ES1,ES2のどちらでも使える
古い機種への対応も視野にいれるなら、機能は少ないが ES1 を選択するべき。
書籍でも ES1ベースの説明になっているようなので、これから勉強するにもES1の方が楽そうです。
うちにあるのは、iPhone3GSと iPod touch 第1世代なので、その意味でもES1が最適です。
巷に溢れている書籍(といっても2冊しか見てませんが)は SDK3.x をベースに書かれている様子で、サンプルプロジェクトを作成しても同じコードができないようです。
となれば選択肢は2つ
- あきらめて SDK3.x を使って作成する(既にダウンロードしたものはもっている)
- SDK4.2の内容を解読して書き換える。
後者の解読をして、SDK4.2の環境でOpenGL ES1で開発できるようにしました。
ベースになるファイルは ◯◯◯◯ViewController.m
◯◯◯◯は作成したプロジェクト名
awakeFromNibが初期化ルーチン
- (void)awakeFromNib { EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; if (!aContext) { aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; } if (!aContext) NSLog(@"Failed to create ES context"); else if (![EAGLContext setCurrentContext:aContext]) NSLog(@"Failed to set ES context current"); self.context = aContext; [aContext release]; [(EAGLView *)self.view setContext:context]; [(EAGLView *)self.view setFramebuffer]; if ([context API] == kEAGLRenderingAPIOpenGLES2) [self loadShaders]; animating = FALSE; animationFrameInterval = 1; self.displayLink = nil; }
赤字部分でES2があればES2用のコンテキストを作成して、作れなければES1用のコンテキストを作成しています。
赤字部分を次の1行だけに変更
EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 ];
これで ES1のコンテキストが必ず作成されます。
drawFrameが描画ルーチン
- (void)drawFrame { [(EAGLView *)self.view setFramebuffer]; (略) if ([context API] == kEAGLRenderingAPIOpenGLES2) { // Use shader program. glUseProgram(program); // Update uniform value. glUniform1f(uniforms[UNIFORM_TRANSLATE], (GLfloat)transY); transY += 0.075f; // Update attribute values. glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); glEnableVertexAttribArray(ATTRIB_VERTEX); glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, 1, 0, squareColors); glEnableVertexAttribArray(ATTRIB_COLOR); // Validate program before drawing. This is a good check, but only really necessary in a debug build. // DEBUG macro must be defined in your debug configurations if that's not already the case. #if defined(DEBUG) if (![self validateProgram:program]) { NSLog(@"Failed to validate program: %d", program); return; } #endif } else { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f, (GLfloat)(sinf(transY)/2.0f), 0.0f); transY += 0.075f; glVertexPointer(2, GL_FLOAT, 0, squareVertices); glEnableClientState(GL_VERTEX_ARRAY); glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors); glEnableClientState(GL_COLOR_ARRAY); } glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); [(EAGLView *)self.view presentFramebuffer]; }
赤字部分が ES2用のコード、緑字部分が ES1用のコードです。
このままでもその都度判定して、ES1用のコードが動くようになりますが、そもそもES2用のコードはつかわないので判定と赤字部分は消しても良いでしょう。
- (void)drawFrame
{
[(EAGLView *)self.view setFramebuffer];
(略)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, (GLfloat)(sinf(transY)/2.0f), 0.0f);
transY += 0.075f;
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
[(EAGLView *)self.view presentFramebuffer];
}
これでSDK3.x用に書かれた書籍の情報もそのまま使えるんじゃないでしょうか。
私もこれから勉強です。