モデルビューワを作る(OpenGL+MFC) (Visual C++ 2015版)

OpenGLとMFCのDoc/Viewアーキテクチャーを用いて再利用可能なOpenGLビュークラスを作成し、作成したOpenGLビュークラスを用いてモデルビューワを作成する方法を解説します。
使用開発環境はVisual C++ 2015です。
(使用開発環境が Visual C++ 2005 の モデル ビューワ を作る(OpenGL+MFC) (Visual C++ 2005版) もあります。
 OpenGLとWindowsAPIを用いた モデル ビューワ を作る(OpenGL+WindowsAPI) (Visual C++ 2008版) もあります。
 Direct3DとWindowsAPIを用いた モデル ビューワ を作る(Direct3D+WindowsAPI) (Visual C++ 2008版) もあります。)

01.ベースOpenGLビュークラスを作る
OpenGLの初期化処理と終了処理を行い、OpenGLを用いた描画処理の骨格を担う、ベースOpenGLビュークラスを作成します。

02.トラックOpenGLビュークラスを作る
トラッキング(マウス操作による描画領域の回転、拡大縮小、平行移動)に関する処理を担うトラックOpenGLビュークラスを、ベースOpenGLビュークラスの派生クラスとして作成します。

03.ピックOpenGLビュークラスを作る
ピッキング(要素選択)に関する処理を担うピックOpenGLビュークラスを、トラックOpenGLビュークラスの派生クラスとして作成します。

04.モデルビューワを作る
01.~03.で作成したクラスを用いてモデルビューワを作成します。

「03.ピックOpenGLビュークラスを作る」 で作成したプログラムに対して、以下の機能を追加したものを作成します。

描画要素(点、線、面)のON/OFF
マウス操作(回転、平行移動、拡大縮小)のON/OFF
ピック要素(点、線、面)のON/OFF

05.モデルデータ構造を作る
04.で作成したモデルビューワは、表示するモデルデータを描画関数内で定義していました。

モデルデータ構造を作成し、04.で作成したモデルビューワを、モデルデータ構造データを描画するようにします。

06.モデルデータファイル読み込みを作る
05.で作成したモデルビューワは、表示するモデルデータをアプリケーション内で定義していました。

モデルデータファイル読み込み処理を作成し、05.で作成したモデルビューワを、ファイルからモデルデータを読み込んで描画するようにします。(アスキー形式STLファイル読み込み処理を作成します。)

07.描画速度の計測
06.で作成したモデルビューワに、描画速度をステータスバーに表示する機能を付加します。

08.描画の高速化(頂点配列)
05.で作成したモデルビューワの描画処理は、1回の「glBegin関数~glEnd関数」で、1つの描画要素(点、線、三角形)の描画処理であり、複数の描画要素(点、線、三角形)を描画する際には、描画要素の数だけ、「glBegin関数~glEnd関数」を呼び出していました。

頂点配列を利用し、「複数の描画要素(点、線、三角形)の描画処理を、まとめる」ことにより、描画の高速化を行います。

09.描画の高速化(頂点バッファオブジェクトの利用)
08.で作成したモデルビューアの描画処理は、頂点配列を用いた描画処理でした。

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

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

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

10.光源の効果の利用
光源の効果を利用すると、描画されるモデルの面に陰影ができ、より立体感がでます。

09.で作成したモデルビューワに光源の効果を付加します。

11.マテリアルの効果の利用
マテリアルの効果を利用すると、描画されるモデルに質感を与えることができます。

10.で作成したモデルビューワにマテリアルの効果を付加します。

12.「面はすべて同一のマテリアル設定」ではないモデルファイルの描画に対応する
11.で作成したモデルビューワは、モデルファイルの面はすべて同一のマテリアル設定としていました。

マテリアル設定が同一である面の集まりに対してグループというデータ構造を用意し、モデルはグループの集まりであるとするデータ構造を用意することで、「面はすべて同一のマテリアル設定」ではないモデルファイルの描画に対応します。

ついでに、頂点法線ベクトルデータ、面法線ベクトルデータも保持するようにモデルデータ構造を変更します。

13.「面はすべて同一のマテリアル設定」ではないモデルファイルの読み込みに対応する
「面はすべて同一のマテリアル設定」ではないモデルファイルの読み込みに対応します。

12.のファイル読み込み処理は、アスキー形式STLファイル読み込み処理でしたが、新たに、OBJファイル読み込み処理を追加し、読み込むファイルの拡張子により、アスキー形式STLファイル読み込み処理とOBJファイル読み込み処理のどちらかが呼び出されるように変更します。

※STLファイルは、「面はすべて同一のマテリアル設定」であるモデルしか表現できませんが、OBJファイルは、「面はすべて同一のマテリアル設定」でないモデルも表現できます。また、OBJファイルは、頂点ごとに異なる法線ベクトルデータを持ったモデルも表現できます。

14.頂点法線ベクトルデータを使用した描画
13.で作成したモデルビューワは、光源の効果の利用に際して面法線ベクトルデータを使用した描画を行っています。面法線ベクトルデータを使用した描画の場合、面の折れ目が目立ちます。

頂点法線ベクトルデータを使用した描画を行うと、面の折れを目を立たなくすることができます。

参考書籍

書籍名 コメント
OpenGL Programming for WIndows 95 and Windows NT (日本語版) MFCのDOC/VIEWアーキテクチャー上にOpenGL描画処理を実装する方法を丁寧に説明しています。絶版?
「01.ベースOpenGLビュークラスを作る」は、本書籍のプログラムが元になっています。
MFCによるWindows95プログラミング MFCプログラマー必読書です。MFCを使用してプログラミングをするならばこれを読まなくてははじまりません。WindowsプログラミングのイベントドリブンがどうMFCで隠蔽され、プログラマーは何をすべきかを正しく学ぶことができます。始めから終わりまで通して読むべき教科書本です。
OpenGLプログラミングガイド 第2版 OpenGLを使用してプログラミングをするならばこれがなくてははじまりません。必要な時に必要な箇所を参照する辞書本です。