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作成が実施されるようにします。

ModelViewerView.cppのCModelViewerView::OnFileOpen関数内のLoadStlFile関数呼び出し後の
m_model.DestroyArray();
m_model.MakeArray();
をコメントアウトし、
m_model.MakeVBO();
を追加します。

ピック描画のVBO対応

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

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

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

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

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

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

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

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

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

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



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



OpenGLPickView.h のピックOpenGLビュークラスの
メンバ関数
UninitializeOpenGL
をprotected関数、さらにvirtual関数とします。

描画処理のVBO対応

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

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



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

実行

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

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

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

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


09.で作成したモデルビューワの描画速度:1000[fps]前後(数値は、モデルのポリゴン数、PCの性能に依存します)
(08. で作成したモデルビューア と差がでませんでしたが、よりポリゴン数が多いモデルにおいて、描画速度に差が出ます。)

ダウンロード

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

関連ページ

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

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