glVertex関数は画面の更新ごとにそして頂点ごとに関数を呼び出してビデオメモリにデータを送りますので遅くなります
頂点配列は画面の更新ごとに頂点をひとまとめにして送るので呼び出し回数は少なくなります
DisplayListはビデオメモリ上に最初にだけデータを送り画面の更新ごとにはデータを送らなくて済むので非常に高速になります
しかしDisplayListは高速ですが一度送ったデータは変更もアクセスも出来ません
このDisplayListの弱点を無くし、一度最初にデータを送り
なおかつ必要なときだけデータ内容を変更することもできる柔軟で高速な手法がVBOです
頂点配列は画面の更新ごとに頂点をひとまとめにして送るので呼び出し回数は少なくなります
DisplayListはビデオメモリ上に最初にだけデータを送り画面の更新ごとにはデータを送らなくて済むので非常に高速になります
しかしDisplayListは高速ですが一度送ったデータは変更もアクセスも出来ません
このDisplayListの弱点を無くし、一度最初にデータを送り
なおかつ必要なときだけデータ内容を変更することもできる柔軟で高速な手法がVBOです
glBindBuffer(vboの種類,buffer)vboの種類を設定します
頂点や配列や色などの配列であれば
GL_ARRAY_BUFFER
インデックスの配列であれば
GL_ELEMENT_ARRAY_BUFFER
になります
glBufferData(vboの種類、配列のサイズ、配列のポインタ、アクセス方法の種類)vboに実際のメモリ上のデータを結びつけます
アクセス方法の種類は
GL_STATIC_DRAW
と
GL_DYNAMIC_DRAW
があり
途中でアクセスしてデータを変更する場合はDYNAMICにします
glBufferSubData(vboの種類、offset, 配列のサイズ、配列のポインタ)glBufferSubDataはオフセットを指定していくつもの種類の配列同士の間隔を
開けて同時にビデオメモリにデータを送れるようにする関数です
この関数を利用することで
頂点配列と法線配列やUV配列などを同時に送ることができます
void initVBO() { glGenBuffers(1, &vboBuffer); glBindBuffer(GL_ARRAY_BUFFER, vboBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vx1)+sizeof(normal1)+sizeof(color1), 0, GL_STATIC_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vx1), vx1); glBufferSubData(GL_ARRAY_BUFFER, sizeof(vx1), sizeof(normal1), normal1); glBufferSubData(GL_ARRAY_BUFFER, sizeof(vx1)+sizeof(normal1), sizeof(color1), color1); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &vboIxBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIxBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ix1), ix1, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glPushMatrix(); glTranslatef(0, 0, -5); glRotatef(xRot,1,0,0); glRotatef(yRot,0,1,0); glRotatef(zRot,0,0,1); glBindBuffer(GL_ARRAY_BUFFER, vboBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIxBuffer); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glNormalPointer(GL_FLOAT, 0, (void*)sizeof(vx1)); glColorPointer(3, GL_FLOAT, 0, (void*)(sizeof(vx1)+sizeof(normal1))); glVertexPointer(3, GL_FLOAT, 0, 0); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (void*)0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glPopMatrix(); xRot += 0.2; yRot += 0.2; }
上記の描画を頂点配列でやろうとするならこのように書きます
立方体データ
ソース全文 vbo1.cpp
https://image01.seesaawiki.jp/p/o/pascal-memo/H3CK...
頂点配列への書き換え版 vbo1linux.cpp
https://image01.seesaawiki.jp/p/o/pascal-memo/RaEP...
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glNormalPointer(GL_FLOAT, 0, normal1); glColorPointer(3, GL_FLOAT, 0, color1); glVertexPointer(3, GL_FLOAT, 0, vx1); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (void*)ix1); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
立方体データ
const GLfloat lengthEdge = 0.7; GLfloat vx1[] = { lengthEdge, lengthEdge, lengthEdge, -lengthEdge, lengthEdge, lengthEdge, -lengthEdge,-lengthEdge, lengthEdge, lengthEdge,-lengthEdge, lengthEdge, lengthEdge, lengthEdge, lengthEdge, lengthEdge,-lengthEdge, lengthEdge, lengthEdge,-lengthEdge,-lengthEdge, lengthEdge, lengthEdge,-lengthEdge, lengthEdge, lengthEdge, lengthEdge, lengthEdge, lengthEdge,-lengthEdge, -lengthEdge, lengthEdge,-lengthEdge, -lengthEdge, lengthEdge, lengthEdge, -lengthEdge, lengthEdge, lengthEdge, -lengthEdge, lengthEdge,-lengthEdge, -lengthEdge,-lengthEdge,-lengthEdge, -lengthEdge,-lengthEdge, lengthEdge, -lengthEdge,-lengthEdge,-lengthEdge, lengthEdge,-lengthEdge,-lengthEdge, lengthEdge,-lengthEdge, lengthEdge, -lengthEdge,-lengthEdge, lengthEdge, lengthEdge,-lengthEdge,-lengthEdge, -lengthEdge,-lengthEdge,-lengthEdge, -lengthEdge, lengthEdge,-lengthEdge, lengthEdge, lengthEdge,-lengthEdge }; GLuint ix1[] = { 0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4, 8, 9,10, 10,11, 8, 12,13,14, 14,15,12, 16,17,18, 18,19,16, 20,21,22, 22,23,20 };//size is 36 GLfloat normal1[] = { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 }; const GLfloat colorPlate = 0.5; GLfloat color1[] = { colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate, colorPlate,colorPlate,colorPlate };
ソース全文 vbo1.cpp
https://image01.seesaawiki.jp/p/o/pascal-memo/H3CK...
頂点配列への書き換え版 vbo1linux.cpp
https://image01.seesaawiki.jp/p/o/pascal-memo/RaEP...
コメントをかく