頂点配列




VertexArray(頂点配列)

DESC 描画に使う頂点をひとまとめにして、OpenGL へ転送しておくことで 描画処理を高速化する機能。 頂点を配列として扱うことでまとまった処理ができ、 関数呼び出しの オーバーヘッドを減らすこともできる。 Application は index で頂点を指定する 共有頂点の処理の重複にも効果がある( Cashe )
// 頂点の数だけ関数呼び出しのオーバーヘッドがかかる。 float vtx[3*100][3]; glBegin( GL_TRIANGLES ); for( int i=0; i<300; i++ ){ glVertex3fv( vtx[i] ); } glEnd(); // 頂点の配列を指定して一度の描画コマンドで済ます。 glVertexPointer( 3, GL_FLOAT, 0, vtx ); glDrawArrays( GL_TRIANGLES, 0, 300 );
頂点配列を利用する場合は、glBegin() - glEnd() の部分のコードを置き換える。 頂点配列のデータを指定して、頂点配列の使用を有効化した後に描画コールをするだけ。
App::onDraw() { // 頂点データ // 描画コール毎に頂点データが転送されるため、アプリケーション側は描画コールまではデータを保持する必要がある。 float vtx[] = { 0, 0, 0, 100, 0, 0, 50, 200, 0, }; // 使用する頂点属性を宣言する。( データを指定するだけでは描画に利用されない。) glEnableClientState( GL_VERTEX_ARRAY ); // 頂点配列として使うデータを指定する。 glVertexPointer( 3, GL_FLOAT, 0, vtx ); // 描画する。 glDrawArrays( GL_TRIANGLES, 0, 3 ); }
SAMPLE https://www.dropbox.com/s/bwh9jjd44tfoirp/vertex_array.exe( 頂点配列 ) 頂点配列には、単一のデータではなく複数の頂点属性を混ぜることができる。 実装によってはこちらの方が高速に処理できる。
struct Vertex { float pos[3]; float col[3]; }; Vertex v[] = { { 0, 0, 0, 1, 0, 0 }, { 100, 0, 0, 1, 1, 1 }, { 50, 100, 0, 0, 1, 0 }, }; // インターリーブ型にする場合は stride で間隔を指定する。 glVertexPointer( 3, GL_FLOAT, sizeof(Vertex), v ); glColorPointer ( 3, GL_FLOAT, sizeof(Vertex), v[0].col ); // カラーと座標を使う。 glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_COLOR_ARRAY ); glDrawArrays( GL_TRIANGLES, 0, 3 );
void drawPrimitiveArray() { // Texture の影響をうけないようにする glDisable( GL_TEXTURE_2D ); const float s = 30; // Position static float vtx[] = { 0, 0, 0, s, 0, 0, s, s, 0, }; // Color static GLfloat col[] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, }; // Color , Positon の頂点配列を有効化 // ポインタは場所を指定するだけで使用するにはこの関数をよびだす // glEnableClientState( GL_COLOR_ARRAY ); glEnableClientState( GL_VERTEX_ARRAY ); // 頂点配列へののアドレスと要素数を指定する glColorPointer( 3, GL_FLOAT, 0, col ); glVertexPointer( 3, GL_FLOAT, 0, vtx ); static unsigned short idx[] = { 0, 1, 3,}; // Triangle を描画 glDrawElements( GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, idx ); } }



glVertexPointer

SYNTAX void glVertexPointer( GLint size, // 頂点座標の要素数 ( XYZ ならば3 ) GLenum type, // データ型 GLsizei stride, // 次の頂点の座標データまでのバイトサイズ。 const GLvoid *pointer // Dataへのポインタ ) DESC 描画に使う頂点配列のデータ( 場所、型、フォーマット )を指定する。 POINT stride, pointer パラメータはデータの指定方法によって異なる。 stride 0 : pointer で指定した配列には座標データが連続して並んでいるとみなされる。 N : pointer で指定するのはインターリーブ配列で, 次の座標データまでの間隔をバイトで指定する。 ( 実装によってはこちらの方が効率的 ) pointer VBO がバインドされている場合は VBO のバイトオフセットとして扱われる。 バインドされていない場合は、クライアント側のメモリアドレス。 WARNING Type にあう Alignment に各要素が配置されている必要がある


glTexCoordPointer

DESC 頂点配列のテクスチャ座標データを指定する。


glColorPointer

SYNTAX void glColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); DESC The glColorPointer function defines an array of colors. POINT pointer は VBO がバインドされている場合は VBO 内にあるカラーデータまでのオフセットを指定する。 VBO がバインドされていない場合は アプリケーションのメモリの値になる。 BLEND OFF == glDisable( GL_BLEND ); Fragment col.w = 1; の値が FrameBuffer に格納される. BLEND ON Fragment col.w = a; BlendExp にしたがって格納。 要は [ COLOR 成分 ]と同様にふるまう. と考えること。 POINT Alpha も設定できる。 glCopyTexImage2D() では Alpha 成分も Copy できる. !


glVertexAttribPointer

VERSION 2.0 SYNTAX void glVertexAttribPointer( GLuint index, // 頂点属性の番号 GLint size, // 要素数( 1−4 ) GLenum type, GLboolean normalized, // [ -1 : 1 ], [ 0 : 1 ] に正規化するかどうか GLsizei stride, const GLvoid * pointer); DESC 汎用型の頂点データを指定する。 おおまかには glVertexPointer() などと使い方は同じ。 シェーダで追加の頂点属性を指定する時などに利用する。


glDrawArrays

SYNTAX glDrawArrays( mode, // プリミティブモード offset, // 頂点配列の開始オフセット count // 描画に使う頂点数の数 ); DESC 格納した頂点バッファを描画する glDrawElements とは違い 頂点配列へのインデックスを指定しないので 頂点バッファのデータは描画順にならんでないとだめ [0]-- [3] | | | | [1]-- [2]
// 四角形をひとつ // 0 番目から 4 個 glDrawArrays( GL_QUADS, 0, 4 );



glDrawElements

SYNTAX void glDrawElements( GLenum mode, // Primitive 形式の指定 GLsizei count, // Rendering する頂点の個数 GLenum type,     // Index Data の型( GL_UNSIGNED_BYTE | GL_UNSIGNED_SHORT | GL_UNSIGNED_BYTE ) const GLvoid *idx // 頂点配列をさす Index ); DESC 頂点配列を使った描画コマンドのひとつ 指定した index 列がさす頂点で描画する glVertexPointer, glNormalPointer, glTexCoordPointer で指定した頂点配列から index を使ってとる TIP BufferObject に Bind されているときは indices は BufferObject への offset として解釈される
// 頂点配列を指定 static float vtx[] = { 0, 0, 0, 1, 0, 0, 1, 1, 0, }; // 頂点配列へのインデックス配列 0 1 2 を指定する static u16 idx[] = { 0, 1, 2 }; glVertexPointer( 3, GL_FLOAT, 0, vtx ); // BufferObject を Bind しているときは glBindBuffer( GL_ARRAY_BUFFER, id ); // idx が指す先は BufferObject からの offset として扱われる glDrawElements( GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, idx );



glDrawRangeElements

SYNTAX glDrawRangeElements DESC glDrawElements を最適化したもので頂点 index の範囲を制限する


glEnableClientState

SYNTAX void glEnableClientState( GLenum array ) DESC 有効にする配列( VertexArray )を指定する VertexArray の Command を発行するとき, 有効になっている Data のみを利用する glEnable() と概念は同じだが Client 側の State を変更する glEnable() は サーバー側のステートを有効にする glEnableClientState という名前は displaylist に格納できないことに由来している ( data がクライアント側に残るから ) TIP MultiTexture の場合は. UnitActive Unit のみ影響をうける
// 頂点と法線を使って描画することを宣言 glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_NORMAL_ARRAY ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); // 描画 draw();