■ 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
頂点配列
頂点配列には、単一のデータではなく複数の頂点属性を混ぜることができる。
実装によってはこちらの方が高速に処理できる。
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 unsigned short 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();