OpenGL ESを使って立方体を描いてみた
ちょっとOpenGL ESの勉強をしてみたいなと思い、Jeff LaMarcheさんの『http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-table-of.html』を読み始めました。LaMarcheさんは、私が今年の1月に初めてiPhone/Objective-Cの勉強に使った本、『Begining iPhone Development』(Dave Markさんとの共著)の筆者だったので、名前だけは知っていました。余談ですが、確か、Apressっていう出版社の存在もこの本で初めて知ったのかな。
LaMarcheさんの説明はとても丁寧で、OpenGLどころか今まで3Dグラフィックスについてなんら勉強してこなかった私には、最適のように思えます。ボリューム的に本一冊分はあるので、時間はかかるかもしれないけど、最後まできちんと読みたいです。現在は、第二部の『http://iphonedevelopment.blogspot.com/2009/04/opengl-es-from-ground-up-part-2-look-at.html』を終わりました。
この記事の最後では、LaMarcheさんはあえて正二十面体を選んで解説してくれています。
Let's finish our tutorial with a real, honest-to-goodness 3D shape:an icosahedron. Everybody else does cubes, but we're going to be geeky and do a twenty-sided die(sans numbers).
記事のサンプルも動かしてみましたが、それだけでは理解が深まらないと思い、私は立方体も描いてみることにしました。
何せ初めてだったもので、vertices[]を書く際、展開図を描いて、三角形に分解して、それぞれの頂点座標を頭の中で適当にプロットしました。なんでこんなヘンテコな順番でアルファベットを頂点に割り当てたのか、今、ノートを見返してもわからないのですが。
最初、glDrawElementsの第一引数がGL_TRIANGLESだったので、正しく描けませんでした。これは私が正二十面体のサンプルソースをそのまま使っていたのが原因で、GL_TRIANGLE_STRIPを指定しました。
- (void)drawView:(UIView *)theView { static const Vertex3D vertices[] = { {0.5, 0.5, 0}, // C {-0.5, 0.5, 0}, // G {-0.5, -0.5, 0}, // H {0.5, -0.5, 0}, // D {1.0, 1.0, -0.5}, // A {1.0, 0.0, -0.5}, // B {0.0, 1.0, -0.5}, // E {0.0, 0.0, -0.5} // F }; static const Color3D colors[] = { {1.0, 0.0, 0.0, 1.0}, // C {0.0, 1.0, 0.0, 1.0}, // G {1.0, 1.0, 0.0, 1.0}, // H {0.0, 0.0, 1.0, 1.0}, // D {1.0, 1.0, 0.0, 1.0}, // A {0.0, 1.0, 0.0, 1.0}, // B {1.0, 1.0, 0.0, 1.0}, // E {0.0, 1.0, 0.0, 1.0} // F }; static const GLubyte cubeFaces[] = { 1, 2, // G -> H -> 0, 3, // C -> D -> 4, 5, // A -> B -> 6, 7, // E -> F -> 1, // G(-> H) 6, 1, // E -> G -> 4, 0, // A -> C 2, 7, // H -> F -> 3, 5 // D -> B }; glLoadIdentity(); glTranslatef(0.0f, 0.0f, -3.0f); glClearColor(0.7, 0.7, 0.7, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glColor4f(1.0, 0.0, 0.0, 1.0); glVertexPointer(3, GL_FLOAT, 0, vertices); glColorPointer(4, GL_FLOAT, 0, colors); glDrawElements(GL_TRIANGLE_STRIP, 51, GL_UNSIGNED_BYTE, cubeFaces); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); }