ProgrammingのTipなど

VBO Vertex Buffer Object

glVertex関数は画面の更新ごとにそして頂点ごとに関数を呼び出してビデオメモリにデータを送りますので遅くなります
頂点配列は画面の更新ごとに頂点をひとまとめにして送るので呼び出し回数は少なくなります
DisplayListはビデオメモリ上に最初にだけデータを送り画面の更新ごとにはデータを送らなくて済むので非常に高速になります
しかしDisplayListは高速ですが一度送ったデータは変更もアクセスも出来ません
このDisplayListの弱点を無くし、一度最初にデータを送り
なおかつ必要なときだけデータ内容を変更することもできる柔軟で高速な手法がVBOです
glGenBuffer
glGenBuffer(作成するvboの数、&buffer)
vboを作成します
bufferはvboを識別する名札のようなものです
glBindBuffer
glBindBuffer(vboの種類,buffer)
vboの種類を設定します
頂点や配列や色などの配列であれば
GL_ARRAY_BUFFER
インデックスの配列であれば
GL_ELEMENT_ARRAY_BUFFER
になります
glBufferData
glBufferData(vboの種類、配列のサイズ、配列のポインタ、アクセス方法の種類)
vboに実際のメモリ上のデータを結びつけます
アクセス方法の種類は
GL_STATIC_DRAW

GL_DYNAMIC_DRAW
があり
途中でアクセスしてデータを変更する場合はDYNAMICにします
複数の種類のデータを設定する
複数の種類のデータを設定するには
glBufferDataの配列のポインタを0にして
glBufferSubDataで設定します
glBufferSubData
glBufferSubData(vboの種類、offset, 配列のサイズ、配列のポインタ)
glBufferSubDataはオフセットを指定していくつもの種類の配列同士の間隔を
開けて同時にビデオメモリにデータを送れるようにする関数です
この関数を利用することで
頂点配列と法線配列やUV配列などを同時に送ることができます
vbo設定例
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;
}
頂点配列での書き方
上記の描画を頂点配列でやろうとするならこのように書きます
  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...

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu

メニュー2

開くメニュー

閉じるメニュー

  • アイテム
  • アイテム
  • アイテム
【メニュー編集】

管理人/副管理人のみ編集できます