Vertex array†OpenGLでポリゴンなどを描画するときは, double v0[3] = {0, 0, 0}; double v1[3] = {1, 0, 0}; double v2[3] = {0, 1, 0}; glBegin(GL_TRIANGLES); glVertex3dv(v0); glVertex3dv(v1); glVertex3dv(v2); glBegin(GL_TRIANGLES); などのようにglVertexで一つ一つ指定します. しかし,大量の頂点データがある場合,毎回glVertex関数を呼び出すのはパフォーマンス上あまり良くありません. そこで,Vertex arrayを用います. GLdouble vertices[] = { 0, 0, 0, 1, 0, 0, 1, 1, 0 }; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_DOUBLE, 0, vertices); int num_of_vertices = sizeof(vertices)/sizeof(GLdouble); glDrawArrays(GL_TRIANGLES, 0, num_of_vertices); glDisableClientState(GL_VERTEX_ARRAY); 配列に格納した頂点データをOpenGLに転送,描画します. それぞれの関数は,
glDrawElements†ポリゴンデータの表現には通常,頂点列とその幾何構造を用います. そのようなデータの描画時にはglDrawElements()を用います. GLdouble vertices[] = { 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0 }; GLuint indices[] = { 0, 1, 2, 0, 2, 3 }; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_DOUBLE, 0, vertices); int num_of_indices = sizeof(indices)/sizeof(GLuint); glDrawElements(GL_TRIANGLES, num_of_indices, GL_UNSIGNED_INT, indices); glDisableClientState(GL_VERTEX_ARRAY); indicesのある範囲だけ使いたい場合は,glDrawRangeElement(mode, start, end, count, type, indices)を用います. また,複数のindicesをまとめて指定したい場合は,glMultiDrawElementsがあります. Interleaved array†1つのarrayに複数の種類のデータ(e.g. ColorとVertex)を含めたい場合は, glInterleavedArraysが使えます.例えば,頂点の色と座標の場合, GLfloat col_and_vert[] = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 5.0, 5.0, 0.0 }; glInterleavedArrays(GL_C3F_V3F, 0, col_and_vert); glDrawArrays(GL_TRIANGLES, 0, 3); col_and_vertには{頂点1の色,頂点1の座標,頂点2の色,頂点2の座標,... }の順番にデータが格納されています. glInterleavedArraysの第一引数は配列の型と並びを指定します.GL_C3F_V3FはglColorPointerに対応する3要素のfloatと glVertexPointerに対応する3要素のfloatが並んでいることを示しています. このほかにも,GL_V2F, GL_V3F, GL_C4UB_V2F, GL_C4UB_V3F, GL_C3F_V3F, GL_N3F_V3F, GL_C4F_N3F_V3F, GL_T2F_V3F, GL_T4F_V4F, GL_T2F_C4UB_V3F, GL_T2F_C3F_V3F, GL_T2F_N3F_V3F, GL_T2F_C4F_N3F_V3F, GL_T4F_C4F_N3F_V4F が指定できます.UBはGL_UNSIGNED_BYTE,Tはテクスチャ座標に対応します. また,構造体を用いると, struct Vertex { GLfloat color[4]; GLfloat normal[3]; GLfloat vertex[3]; }; vector<Vertex> inter_array; inter_array.resize(N); ... glInterleavedArrays(GL_C4F_N3F_V3F, 0, &inter_array[0]); glDrawArrays(GL_TRIANGLES, 0, N); 値の格納にはCの配列ではなくSTLのvectorを用いました. vectorは&inter_array[0]を渡すことで配列と互換性を持っています. |