OpenGL - VBO
をテンプレートにして作成
[
トップ
|
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
Vertex Buffer Object(VBO)について
**VBOとは [#scd59b12]
[[OpenGL - Vertex array]]はOpenGLのAPIの呼び出しを減らす...
パフォーマンスを大きく改善することができるものの,
頂点データは描画呼び出し毎にクライアント側のメモリからサ...
一方,GPU側で完全に格納されたデータで呼び出しのたびに実行...
ディスプレイリストではAPI呼び出しのオーバーヘッドをなくす...
しかし,ディスプレイリストは一度コンパイルされれば,ディ...
これらの問題を解決するのが Vertex Buffer Object(VBO) です.
VBOは頂点データを格納するGPU側のメモリに置かれたバッファ...
クライアント側のメモリ上の配列と同じように扱え,
glVertexPointerなどに直接渡すことができます.
また,ディスプレイリストと違い,クライアント側のメモリス...
クライアントからの読込みや変更が可能となります.
**VBO作成手順 [#vf0f2aa5]
VBOの作成にはGL拡張をいくつか使います.
[[GLEW:http://glew.sourceforge.net/]]などをインクルード,...
VBOの作成はテクスチャを作成するのと同じような手順です.
+[[glGenBuffers:http://www.opengl.org/sdk/docs/man/xhtml/...
void glGenBuffers(GLsizei n, GLuint *buffers);
nに生成する数を指定し,bufferに生成したVBO名が返ってくる.
+[[glBindBuffer:http://www.opengl.org/sdk/docs/man/xhtml/...
void glBindBuffer(GLenum target, GLuint buffer);
targetにはVBOに何のデータ(頂点,インデックス,ピクセル)を...
(GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER).
bufferはVBO名.
+[[glBufferData:http://www.opengl.org/sdk/docs/man/xhtml/...
void glBufferData(GLenum target, GLsizeiptr size, const ...
targetは2と同じで,sizeには転送するサイズ,dataにはクライ...
もしdataにNULLが指定されたらデータは転送されない.usageは...
GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC...
のどれかを指定する.
--STATIC : VBOデータ変更なし.(modified once and used man...
--DYNAMIC : VBOデータが頻繁に変更される.(modified repeat...
--STREAM : VBOデータが毎フレーム変更される.(modified onc...
--DRAW : VBOデータはアプリケーションから転送され,OpenGL...
--READ : VBOデータはGLから転送され,アプリケーションで読...
--COPY : VBOデータはGLから転送され,OpenGL描画に用いられ...
他に範囲データ転送やVBO破棄命令などがある.
-[[glBufferSubData:http://www.opengl.org/sdk/docs/man/xht...
void glBufferSubData(GLenum target, GLintptr offset, GLs...
-[[glDeleteBuffers:http://www.opengl.org/sdk/docs/man/xht...
void glDeleteBuffers(GLsizei n, const GLuint * buffers);
**VBOを使った描画例 [#k516f512]
まず,VBOを作成します.
#code(C){{
// VBO作成
vector<Vec3> vertices;// = { 0, 0, 0, 1, 0, 0, 1, 1, 0...
vertices.push_back(Vec3(0, 0, 0));
vertices.push_back(Vec3(1, 0, 0));
vertices.push_back(Vec3(1, 1, 0));
vertices.push_back(Vec3(0, 1, 0));
vector<int> indices;// = { 0, 1, 2, 0, 2, 3 };
indices.push_back(0);
indices.push_back(1);
indices.push_back(2);
indices.push_back(0);
indices.push_back(2);
indices.push_back(3);
glGenBuffers(1, &vrtVBO);
glBindBuffer(GL_ARRAY_BUFFER, vrtVBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*3*sizeof(d...
glGenBuffers(1, &idxVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idxVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*siz...
}}
この処理は頂点,インデックスデータが変わらなければ1回だけ...
次に描画時には,
#code(C){{
glBindBuffer(GL_ARRAY_BUFFER, vrtVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idxVBO);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_DOUBLE, 0, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}}
glBindBufferでVBOをバインドして,あとはVertex arrayと同じ...
データの場所のポインタには0を指定します(オフセット値0とい...
使い終わったら削除します.
#code(C){{
glDeleteBuffers(1, &vrtVBO);
glDeleteBuffers(1, &idxVBO);
}}
**VBOデータの変更 [#pc0bdfaa]
VBOはクライアント側のメモリスペースにバッファをマッピング...
データの修正は以下の手順で行います.
-[[glBindBuffer:http://www.opengl.org/sdk/docs/man/xhtml/...
-[[glMapBuffer:http://www.opengl.org/sdk/docs/man/xhtml/g...
void* glMapBuffer(GLenum target, GLenum access);
targetはglBindBufferで指定したものと同じ,accessはバッフ...
アクセス権限を指定する(GL_READ_ONLY, GL_WRITE_ONLY, GL_RE...
返値でデータへのポインタを取得する.もしバッファオブジェ...
-データを修正
-[[glUnmapBuffer:http://www.opengl.org/sdk/docs/man/xhtml...
GLboolean glUnmapBuffer(GLenum target);
マップしたバッファオブジェクトが使用される前にアンマップ...
データの修正の例は以下.
#code(C){{
void ModifyVBO(void)
{
glBindBuffer(GL_ARRAY_BUFFER, vrtVBO);
double *ptr = (double*)glMapBuffer(GL_ARRAY_BUFFER, GL_W...
static double ang = 0.0;
if(ptr){
for(int i = 1; i <= 2; ++i){
ptr[3*i] = cos(RX_TO_RADIANS(ang));
ptr[3*i+2] = sin(RX_TO_RADIANS(ang));
}
glUnmapBuffer(GL_ARRAY_BUFFER);
ang = (ang < 360) ? ang+1 : 0.0;
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}}
** [#m4abd025]
終了行:
Vertex Buffer Object(VBO)について
**VBOとは [#scd59b12]
[[OpenGL - Vertex array]]はOpenGLのAPIの呼び出しを減らす...
パフォーマンスを大きく改善することができるものの,
頂点データは描画呼び出し毎にクライアント側のメモリからサ...
一方,GPU側で完全に格納されたデータで呼び出しのたびに実行...
ディスプレイリストではAPI呼び出しのオーバーヘッドをなくす...
しかし,ディスプレイリストは一度コンパイルされれば,ディ...
これらの問題を解決するのが Vertex Buffer Object(VBO) です.
VBOは頂点データを格納するGPU側のメモリに置かれたバッファ...
クライアント側のメモリ上の配列と同じように扱え,
glVertexPointerなどに直接渡すことができます.
また,ディスプレイリストと違い,クライアント側のメモリス...
クライアントからの読込みや変更が可能となります.
**VBO作成手順 [#vf0f2aa5]
VBOの作成にはGL拡張をいくつか使います.
[[GLEW:http://glew.sourceforge.net/]]などをインクルード,...
VBOの作成はテクスチャを作成するのと同じような手順です.
+[[glGenBuffers:http://www.opengl.org/sdk/docs/man/xhtml/...
void glGenBuffers(GLsizei n, GLuint *buffers);
nに生成する数を指定し,bufferに生成したVBO名が返ってくる.
+[[glBindBuffer:http://www.opengl.org/sdk/docs/man/xhtml/...
void glBindBuffer(GLenum target, GLuint buffer);
targetにはVBOに何のデータ(頂点,インデックス,ピクセル)を...
(GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER).
bufferはVBO名.
+[[glBufferData:http://www.opengl.org/sdk/docs/man/xhtml/...
void glBufferData(GLenum target, GLsizeiptr size, const ...
targetは2と同じで,sizeには転送するサイズ,dataにはクライ...
もしdataにNULLが指定されたらデータは転送されない.usageは...
GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC...
のどれかを指定する.
--STATIC : VBOデータ変更なし.(modified once and used man...
--DYNAMIC : VBOデータが頻繁に変更される.(modified repeat...
--STREAM : VBOデータが毎フレーム変更される.(modified onc...
--DRAW : VBOデータはアプリケーションから転送され,OpenGL...
--READ : VBOデータはGLから転送され,アプリケーションで読...
--COPY : VBOデータはGLから転送され,OpenGL描画に用いられ...
他に範囲データ転送やVBO破棄命令などがある.
-[[glBufferSubData:http://www.opengl.org/sdk/docs/man/xht...
void glBufferSubData(GLenum target, GLintptr offset, GLs...
-[[glDeleteBuffers:http://www.opengl.org/sdk/docs/man/xht...
void glDeleteBuffers(GLsizei n, const GLuint * buffers);
**VBOを使った描画例 [#k516f512]
まず,VBOを作成します.
#code(C){{
// VBO作成
vector<Vec3> vertices;// = { 0, 0, 0, 1, 0, 0, 1, 1, 0...
vertices.push_back(Vec3(0, 0, 0));
vertices.push_back(Vec3(1, 0, 0));
vertices.push_back(Vec3(1, 1, 0));
vertices.push_back(Vec3(0, 1, 0));
vector<int> indices;// = { 0, 1, 2, 0, 2, 3 };
indices.push_back(0);
indices.push_back(1);
indices.push_back(2);
indices.push_back(0);
indices.push_back(2);
indices.push_back(3);
glGenBuffers(1, &vrtVBO);
glBindBuffer(GL_ARRAY_BUFFER, vrtVBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*3*sizeof(d...
glGenBuffers(1, &idxVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idxVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*siz...
}}
この処理は頂点,インデックスデータが変わらなければ1回だけ...
次に描画時には,
#code(C){{
glBindBuffer(GL_ARRAY_BUFFER, vrtVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idxVBO);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_DOUBLE, 0, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}}
glBindBufferでVBOをバインドして,あとはVertex arrayと同じ...
データの場所のポインタには0を指定します(オフセット値0とい...
使い終わったら削除します.
#code(C){{
glDeleteBuffers(1, &vrtVBO);
glDeleteBuffers(1, &idxVBO);
}}
**VBOデータの変更 [#pc0bdfaa]
VBOはクライアント側のメモリスペースにバッファをマッピング...
データの修正は以下の手順で行います.
-[[glBindBuffer:http://www.opengl.org/sdk/docs/man/xhtml/...
-[[glMapBuffer:http://www.opengl.org/sdk/docs/man/xhtml/g...
void* glMapBuffer(GLenum target, GLenum access);
targetはglBindBufferで指定したものと同じ,accessはバッフ...
アクセス権限を指定する(GL_READ_ONLY, GL_WRITE_ONLY, GL_RE...
返値でデータへのポインタを取得する.もしバッファオブジェ...
-データを修正
-[[glUnmapBuffer:http://www.opengl.org/sdk/docs/man/xhtml...
GLboolean glUnmapBuffer(GLenum target);
マップしたバッファオブジェクトが使用される前にアンマップ...
データの修正の例は以下.
#code(C){{
void ModifyVBO(void)
{
glBindBuffer(GL_ARRAY_BUFFER, vrtVBO);
double *ptr = (double*)glMapBuffer(GL_ARRAY_BUFFER, GL_W...
static double ang = 0.0;
if(ptr){
for(int i = 1; i <= 2; ++i){
ptr[3*i] = cos(RX_TO_RADIANS(ang));
ptr[3*i+2] = sin(RX_TO_RADIANS(ang));
}
glUnmapBuffer(GL_ARRAY_BUFFER);
ang = (ang < 360) ? ang+1 : 0.0;
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}}
** [#m4abd025]
ページ名: