09.描画の高速化(頂点バッファオブジェクトの利用)



08.で作成したモデルビューアの描画処理は、頂点配列を用いた描画処理でした。

頂点配列を用いた描画処理では、glDrawArrays や glDrawElements の呼び出しのたびに、頂点データが、クライアントメモリからグラフィックスメモリへコピーされます。

頂点バッファオブジェクト ( Vertex Buffer Object : VBO ) を用いた描画処理では、頂点データを、事前にクライアントメモリからグラフィックスメモリにコピーしておき、glDrawArrays や glDrawElements の呼び出しのときには、コピー済みの頂点データを用いて描画します。

頂点バッファオブジェクト ( Vertex Buffer Object : VBO ) を用いた描画処理は、頂点配列を用いた描画処理よりも高速に描画されます。

解説

頂点バッファオブジェクト ( Vertex Buffer Object : VBO ) を用いた描画を行うためには、構築処理と、描画処理と、破棄処理を作成する必要があります。

構築処理では、頂点バッファオブジェクトの作成、頂点データのクライアントメモリからグラフィックスメモリへのコピー、を行います。

  1. glGenBuffer関数で、頂点バッファオブジェクトを作成します。
  2. glBindBuffer関数で、作成した頂点バッファオブジェクトをバインドします。
  3. glBufferData関数で、データをクライアントメモリからグラフィックスメモリにコピーします。

描画処理では、頂点バッファオブジェクトをバインドし、バインドした頂点バッファオブジェクトを用いて描画を行います。

  1. glBindBuffer関数で、作成した頂点バッファをバインドします。
  2. glVertexPointer関数は、頂点バッファオブジェクトを使用するときには、配列データのアドレスを渡す代わりに、データのオフセット量を渡します。
  3. glDrawArrays関数を用いて、描画します。

破棄処理では、頂点バッファオブジェクトの削除を行います。

  1. glDeleteBuffer関数で、作成した頂点バッファオブジェクトを削除します。

プロジェクトを開く

08.で作成したモデルビューワプロジェクトを開きます。

モデルデータ構造のVBO対応

モデルクラスについて、

頂点配列に関するメンバー変数、メンバー関数の宣言を削除します。
VBOに関するメンバー変数を追加します。
VBOに関する関数の宣言を追加します。
コンストラクタにVBOに関するメンバー変数の初期化処理を追加します。

Model.hのCModelのクラス宣言の内容を以下のようにします。

VBOの作成と破棄の定義

頂点配列に関する関数の定義を削除します。
VBOに関する2つの関数(作成と破棄)の定義を追加します。
OpenGL拡張機能を使用するためのヘッダーファイルのインクルードを追加します。

Model.cppの内容を以下のようにします。

VBOの作成の関数の呼び出し

ファイルからのモデルデータの読み込み処理の後に、VBO作成が実施されるようにします。

ModelViewer.cpp の WndProc関数の、WM_COMMAND ウィンドウメッセージ処理の、ID_FILE_OPEN コマンド処理の
glrenderer.m_model.DestroyArray();
glrenderer.m_model.MakeArray();
をコメントアウトし、
glrenderer.m_model.MakeVBO();
を追加します。

ピック描画のVBO対応

ピック描画の色配列についても、グラフィックスメモリにコピーするようにします。

モデルビューアレンダラクラスについて、

色配列に関するメンバー変数(m_abt4VertexIdColor、m_abt4TriangleIdColor)を削除します。
色配列に関するメンバー関数(MakeArray、DestroyArray)の宣言を削除します。

VBOに関するメンバー変数(m_auiVboID)を追加します。
VBOに関する関数(MakeVBO、DestroyVBO、GetVertexIdColorVboID、GetTriangleIdColorVboID)の宣言を追加します。
OpenGL初期化処理関数(InitializeOpenGL)、OpenGL終了処理関数(UninitializeOpenGL)の宣言を追加します。

ModelViewerRenderer.hのCModelViewerRendererのクラス宣言の内容を以下のようにします。

ピック描画用のVBOの作成と破棄の定義

ModelViewerRenderer.cppの、
色配列に関する関数の呼び出しを削除します。
色配列に関する関数の宣言を削除します。

コンストラクタに、VBOに関するメンバー変数の初期化処理を追加します。
VBOに関する2つの関数(作成と破棄)の定義を追加します。

ピック描画用のVBOの作成と破棄の関数の呼び出し

モデルビューアーレンダラクラスに、OpenGL初期化処理関数、OpenGL終了処理関数をオーバーライドします。オーバーライドしたのOpenGL初期化処理関数、OpenGL終了処理関数に、VBOの作成と破棄の関数の呼び出しを追加します。



OpenGLRendererBase.h のベースOpenGLレンダラクラスの
メンバ関数
InitializeOpenGL
をprotected関数、さらにvirtual関数とします。



OpenGLRendererPick.h のピックOpenGLレンダラクラスの
メンバ関数
UninitializeOpenGL
をvirtual関数とします。

描画処理のVBO対応

描画処理をVBOに対応した処理に変更します。

ModelViewerRenderer.cpp の CModelViewerRenderer:RenderModel関数の内容を以下のようにします。



ビルドし、エラー、警告がないことを確認します。

実行

実行し、08.で作成したモデルビューワと、描画速度を比較します。

描画速度はステータスバーに表示されます。

fps
frame per second : 1秒間に描画できる回数を表します。数値が大きいほど、描画速度は速いことになります。
spf
second per frame : 1回の描画に要する時間を表します。数値が小さいほど、描画速度は速いことになります。

09.で作成したモデルビューワの描画速度:500[fps]前後(数値はPCの性能に依存します)


08.で作成したモデルビューワの描画速度:333[fps]前後(数値はPCの性能に依存します)

ダウンロード

ソースファイルダウンロード ( ModelViewerOpenGLWinAPI2015_09_vbo.zip )

関連ページ

前項目:08.描画の高速化(頂点配列)

次項目:10.光源の効果の利用