また気がつくと1ヶ月以上経過していて困ったものです。
GUIが使えた方が色々と便利だと思いますので、Qtを使用してみることにしました。
Qt Creatorという統合開発環境があり、Visual Studioなどに慣れていれば容易にGUIプログラミングができそうです。
今回用いたバージョンは、Qt Creator 2.4.1 (Qt 4.7.4 (32 bit))です。
GLEWはいつのものかはわかりませんがそんなに古くは無いと思います。
QtはOpenGLをサポートしており、QGLWidgetクラスを使用すれば、GLSLを使用することができます。
Qtのものをそのまま使用すればいいとは思うのですが、昔GLEWを使用して作ったものが無駄になるのは悲しいので、QGLWidgetでGLEWを使用することにしました。
QtでGLSL準備
まずはQtでGLSLを使用できるまでの方法です。
こちらのページが大変参考になります。以後のお話は[1]と[3]をやった後のお話になっています。
参考サイト
[1] CreatorでOpenGL(v4.7対応):
http://www10.atwiki.jp/bambooflow/pages/312.html[2] QtでOpenGL : クラス:
http://www10.atwiki.jp/bambooflow/pages/316.html[3] Qt CreatorスタートガイドのCreating a Qt Widget Based Application
[1]ではcentralWidgetを格上げしていますが、スクロールバーなども使用してみたかったのでQWidgetとHorizontal Scroll Barを追加してVertical Layoutにしました。
Vertical Layoutなどは[3]が参考になりました。([3]はQt Creatorのようこそページにあります。)

GLSLを使用するためには、[2]のQGLShaderProgramを使用します。
シェーダのソースファイルのパスが、":/vshader.glsl"となっていますが、これはQtのリソースファイルになりますので、リソースファイルとして追加します。
このリソースファイルの追加方法も、[3]をやっておけばわかります。
GLEWの使用方法
続いてGLEWの使用方法です。
ポイントとしては、下記2点になります。
- QGLWidgetより先にglew.h(+glut.h)をインクルードする。
- QGLFunctionsはGLEWと競合してしまうのでインクルードしない。
ちなみにQGLFunctionsをインクルードすると、下記警告が出てビルドに失敗します。
#warning qglfunctions.h is not compatible with GLEW, GLEW defines will be undefined
#warning To use GLEW with Qt, do not include <QtOpenGL> or <QGLFunctions> after glew.h
これだけ読むとglew.hの前にQGLFunctionsをインクルードすれば良さそうですが、そうすると今度はgl.hがglew.hの前に宣言〜的なエラーがでます。
続いて、glewInit()をGLWidget::initializeGL()の最初の辺りで行っておきます。
これを忘れるとプログラムが突然終了してしまいます。
GLSLのプログラムはQtのものを使用しますので、シェーダの切替やテクスチャ名、シェーダにデータを渡すときのLocation等は、[2]で作成したprogramを使用して、program->programId()でシェーダプログラムの番号を取得します。
QtのGUI処理
続いてスクロールバーを動かしたときに視点を回転させる部分です。この辺の使い方はQt的に合っているのかどうかは分かりません。
Qtではメッセージ的なものをシグナル、そのシグナルが発生したときに呼ばれる関数をスロットというようです。
今、MainWindowクラスとGLWidgetクラスがあります。スクロールバーはMainWindow上に配置していますので、スクロールバーの値が変わったというシグナルは、MainWindowクラスに追加されます。
- GLWidgetクラスに、スクロールバーの値が変化したときに呼び出される関数を作成しておきます(setScrollValue(int))。
- 編集でmainwindow.uiをダブルクリックして、デザインを開きます。
- スクロールバーを右クリック→スロットへ移動を選択します。
- シグナルを選択するダイアログが表示されますので、valueChanged(int)を選択します。
- MainWindowクラスに、on_horizontalScrollBar_valueChanged(int value)といったクラスが追加されます。
- GLWidgetクラスのui(OpenGLWidgetという名前にしています)を通じて、GLWidgetクラスのメンバ関数setScrollValue(int)を呼び出します。
void MainWindow::on_horizontalScrollBar_valueChanged(int value)
{
ui->OpenGLWidget->setScrollValue(value);
}
外部ライブラリの追加方法
後はOpenCVや自作のライブラリなどを使用する場合は、そのフォルダの設定を行います。
編集のところのHelloGL.proというプロジェクトファイルをダブルクリックで開きます。
開いたファイルを右クリックすると、ライブラリを追加...というメニューがありますので、それを選択します。
外部ライブラリを選択して「次へ」を押します。
ライブラリファイルとインクルードパスを設定して、プラットフォームやリンク方法を選び、「次へ」で追加します。
そうするとINCLUDEPATHやライブラリのリンクが追記され、使用できるようになります。
(Program Filesのように空白が入る場合は""でくくるなど対策が必要)
Qtのイベント処理
マウスホイールでターゲットからカメラまでの距離を変えたかったので、マウスホイールのイベントを追加しました。
GLWidgetはQWidgetクラスを継承していますので、マウスホイールのイベントを受け取ることができます。
マウスホイールに関するヘッダのインクルード:glwidget.hでQWheelEventをインクルードします。
ホイールイベントの関数(void wheelEvent(QWheelEvent *event);)をヘッダに追加します。
ホイールイベントが発生したときの処理をglwidget.cppに記述します。
void GLWidget::wheelEvent(QWheelEvent *event)
{
int numDegrees = event->delta() / 8;
int numSteps = numDegrees / 15;
m_cameraDistance -= numSteps;
updateGL();
event->accept();
}
実行結果
PMDファイルのねんどろいどみくさんを表示してみました。
スクロールバーで回転、ホイールで前後しています。
GLUTとGLEWを使用したものですので、昔のものが一応利用できそうです。