更新日時:2013-06-16 00:10:26 (Sun)アクセス数: -
glVertexAttribPointer
目次
概要
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
レンダリングに使用する属性インデックスとバッファオブジェクトを関連付けます。
glGenVertexArrays でバッファオブジェクトを GL_ARRAY_BUFFER にバインドしてから実行します。
第 1 引数 index には属性インデックスを指定します。
第 2 引数 size は各頂点属性の要素数で 1 ~ 4 の整数を指定します。
第 3 引数 type では各要素のデータ型を GL_FLOAT, GL_DOUBLE, GL_INT などで指定します。
第 4 引数 normalized を GL_TRUE にすると自動的に正規化されます。
第 5 引数 stride は連続する属性間のバイトオフセットを指定します。
第 6 引数 pointer はバッファの先頭から最初の属性へのバイトオフセットです。
ハンドル array に関連付けられた頂点配列オブジェクトをバインドして利用できる状態にします。
第 1 引数 array には
glGenVertexArrays で生成した頂点配列オブジェクトのハンドルを指定します。
ある頂点配列オブジェクトをバインドすると以前にバインドしていた頂点配列オブジェクトのバインドは自動的に解除されます。
ただし、0 を指定した場合には現在バインドされている頂点配列オブジェクトのバインドの解除だけを実行します。
エラー
- GL_INVALID_VALUE
- 第 1 引数 index が GL_MAX_VERTEX_ATTRIBS 以上である場合に生成されます。
- 第 2 引数 size が 1, 2, 3, 4, GL_BGRA のいずれでも無い場合に生成されます。
- 第 5 引数 stride が負である場合に生成されます。
- GL_INVALID_ENUM
- 第 3 引数 type に無効な値を指定した場合に生成されます。
- GL_INVALID_OPERATION
- 第 2 引数 size が GL_BGRA であり、かつ第 3 引数 type が GL_UNSIGNED_BYTE, GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV のいずれでも無い場合に生成されます。
- 第 3 引数 type が GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV のいずれかであり、かつ第 2 引数 size が 4 でも GL_BGRA でも無い場合に生成されます。
- 第 2 引数 size が GL_BGRA であり、かつ第 4 引数 normalized が GL_FALSE である場合に生成されます。
- GL_ARRAY_BUFFER にバッファオブジェクトが割り当てられておらず、かつ第6引数 pointer に NULL を指定した場合に生成されます。
サンプルコード
以下に、バッファオブジェクトを生成して頂点属性を転送する C++ コードの例を示します。
///**********************************************//**
/// 頂点属性を頂点シェーダに渡します。
/// ここではシェーダのコンパイルとリンクは省略されています。
///**********************************************//**
// バッファオブジェクトへのハンドル
GLuint position_buffer;
GLuint color_buffer;
// 頂点配列オブジェクトへのハンドル
GLuint vao;
// バッファオブジェクトの生成
void CreateBufferObject()
{
// 三角形ポリゴンの位置と色に対応する頂点属性の定義
float positions[] = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.5f, 0.5f, 0.0f };
float colors[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };
// バッファオブジェクトの生成
GLuint vbo[2];
glGenBuffers(2, vbo);
position_buffer = vbo[0];
color_buffer = vbo[1];
// 頂点位置をバッファオブジェクトに転送
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 9, positions, GL_STATIC_DRAW);
// 頂点色をバッファオブジェクトに転送
glBindBuffer(GL_ARRAY_BUFFER, color_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 9, colors, GL_STATIC_DRAW);
}
// 頂点シェーダの入力属性とバッファオブジェクトを対応付ける
void BindVertexAttribute()
{
// 頂点シェーダの vertex_position と vertex_color に属性インデックス 0, 1 をマッピング
glBindAttribLocation(program, 0, "vertex_position");
glBindAttribLocation(program, 1, "vertex_color");
// フラグメントシェーダの出力変数をマッピング
glBindFragDataLocation(program, 0, "fragment_color");
// 頂点配列オブジェクトを 1 つ作成してバインド
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// 頂点位置と頂点色のそれぞれについて頂点属性配列を有効化
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// バッファオブジェクトに転送した頂点位置をインデックス 0 に関連付ける
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL);
// バッファオブジェクトに転送した頂点色をインデックス 1 に関連付ける
glBindBuffer(GL_ARRAY_BUFFER, color_buffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL);
}
// レンダリング
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glFlush();
}
また、この API の第 5 引数 stribe を利用すれば上記コードの 2 つのバッファを 1 つに統合できます。
位置と色の属性データが交互に登場するインタリーブ配列を使用するためには以下のようにコードを修正します。
///**********************************************//**
/// インタリーブ配列を利用して三角形をレンダリングします。
///
/// 頂点位置と頂点色の配列を別々に用意する場合とくらべて参照の局所性に優れるため、
/// キャッシュメモリのヒット率が向上してパフォーマンスを改善できる可能性があります。
///
/// ここではシェーダのコンパイルとリンクは省略されています。
///**********************************************//**
// バッファオブジェクトへのハンドル
GLuint vertex_buffer;
// 頂点配列オブジェクトへのハンドル
GLuint vao;
// 三角形ポリゴンの頂点位置と頂点色を交互に指定する配列
float vertices[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
+0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f,
+0.5f, +0.5f, 0.0f, 0.0f, 1.0f, 0.0f
};
// バッファオブジェクトの生成
void CreateBufferObject()
{
// バッファオブジェクトの生成
glGenBuffers(1, &vertex_buffer);
// 頂点位置と頂点色をまとめてバッファオブジェクトに転送
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
}
// 頂点シェーダの入力属性とバッファオブジェクトを対応付ける
void BindVertexAttribute()
{
// 頂点シェーダの vertex_position と vertex_color に属性インデックス 0, 1 をマッピング
glBindAttribLocation(program, 0, "vertex_position");
glBindAttribLocation(program, 1, "vertex_color");
// フラグメントシェーダの出力変数をマッピング
glBindFragDataLocation(program, 0, "fragment_color");
// 頂点配列オブジェクトを 1 つ作成してバインド
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// 頂点位置と頂点色のそれぞれについて頂点属性配列を有効化
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// バッファオブジェクトに転送した頂点位置をインデックス 0 に関連付ける
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 24, (GLubyte*)(NULL + 0));
// バッファオブジェクトに転送した頂点色をインデックス 1 に関連付ける
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 24, (GLubyte*)(NULL + 12));
}
// レンダリング
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glFlush();
}
参考文献
OpenGLに関連するオススメの本や WEB サイトを紹介します.
ページ右の画像をクリックすると Amazon で参考文献を購入できます.
OpenGL策定委員会, 「OpenGLプログラミングガイド 原著第5版」, ピアソンエデュケーション
- OpenGLの赤本(Red Book)と呼ばれる定番の参考書の日本語版です。
- 少し値は張りますがOpenGLの基本的な使い方が丁寧にまとめられています。
- 初心者の方には敷居が高いかもしれませんがOpenGLを極めるつもりなら必須の教本だと思います。
Mark Segal, Kurt Akeley, Jon Leech, 「OpenGL4.0グラフィックスシステム」, カットシステム
- OpenGLの仕様書の日本語訳です。個人的には翻訳に違和感を覚えることはありませんでした。
- 英語が苦手な方は本書をAPIリファレンスの代わりに利用できます。
- チュートリアルのような内容は含まれていませんので他の書籍との併用をオススメします。
床井 浩平, 「GLUTによるOpenGL入門」, 工学社
- これから OpenGL を初めようとしている方にはこの本がオススメです。
- おそらく OpenGL に関する文献の中では最も敷居が低く 3DCG に関する知識が全くなくても理解しやすいです。
- 少し内容は古いかもしれませんが導入という目的では最高の文献で、私もこの本から OpenGL に入門しました。
床井 浩平, 「GLUTによるOpenGL入門2 テクスチャマッピング」, 工学社
- 上の「GLUT によるOpenGL入門」の続編です。
- 前作の内容では物足りなかった方は本書を読むことで 3DCG の表現力が大幅に広がります。
- 引き続き平易な内容となっており、前作を読破した方であれば難なく理解できると思います。
David Wolff , 「OpenGL 4.0 シェーディング言語 -実例で覚えるGLSLプログラミング-」, ボーンデジタル
- 最近のゲームに見られるようなリアルな映像をつくりだすにはプログラマブル・シェーダという機能が欠かせません。
- 床井 浩平さんの「GLUTによるOpenGL入門2 テクスチャマッピング」でもシェーダに関しては少しだけ触れられていますが、書籍の後半で軽く紹介されているだけでいささか物足りない内容ではありますので、本格的に学ぶためにこの本の購入をオススメします。
質問・コメント欄
最終更新:2013年06月16日 00:10