OpenGLで一番高速な描画命令は?

一番高速な描画方法はなんでしょうか?

まぁまず一番低速な描画命令は

float* verarray = new float[9];
glBegin(GL_TRIANGLE);
glVertex3fv(&verarray[0])^Z;
glVertex3fv(&verarray[3]);
glVertex3fv(&verarray[6]);
glEnd()

ですね。

理由は

  • 三角形の頂点毎に毎回関数を呼び出す
  • 頂点の座標を使用する度に送る


そもそも座標のデータはポインタにするべきです。

どういうものかというと座標のデータを配列としてメモリ上に作成し,そのポインタを登録してポリゴンの描画は配列のインデックスを渡す方法です。

float* verarray = new float[9];
glVertexPointer(3, GL_FLOAT, 0, verarray);
glBegin(GL_TRIANGLE);
glArrayElement(0);
glArrayElement(3);
glArrayElement(6);
glEnd();


上記方法でもまだ遅いです。

というのも関数をたくさん呼び出す問題が残っています。
これをクリアする方法は

float* verarray = new float[9];
unsigned int* index = new unsigned int[9];
glVertexPointer(3, GL_FLOAT, 0, verarray);
glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, index);

これで関数の呼び出しがなくなりました。
と同時にこの方法はNvidia製のグラフィックカードなら頂点データのキャッシュが有効になる方法です。
そこら辺の詳細は次のPDFが詳しいです。
http://www.sci.utah.edu/~bavoil/opengl/bavoil_trimeshes_2005.pdf

ゲームやCAE等でたくさんのポリゴンを使う場合はまぁなるべく三番目の方法がいいということですね。
実際はまぁそうじゃないこともあるでしょう。
それに上の例ではテクスチャのUV値や法線には触れませんでした。

ちなみに法線はフラットシェーディングとスムースシェーディングでは描画に必要な法線の数が異なります。


頂点データのキャッシュについてはまた次回。