QtCreator-2.5.0 + QtOpenGL + GLUT ==> teapot
(いちおう)エディターたるVimから、IDEたるQtCreatorでの開発を勉強中。先ずはお約束の第一歩、teapotの備忘録。
プロジェクトをQtの雛形から作成
- File --> New file or Project (CTRL+N)
- Projects: Applications --> Qt Gui Application
以降、仮にプロジェクト名称を"hoge"としたものとして進める。
ウィザードに従い、特に困る事は無く、
- hoge.pro
- Headers
- mainwindow.h
- Sources
- main.cpp
- mainwindow.cpp
- Forms
- mainwindow.ui
が生成される。バージョン管理システムとしてgitを仕込むのもプロジェクト作成時にまとめてできる。
この時点で既にビルド&実行してもフォームが見えるだけのアプリが立派に動作してくれる。
QtOpenGL を組み込む
どうやら Qt で OpenGL を扱う標準的な方法として、 QtOpenGL なるAPIがあるらしい。
プロジェクトに QtOpenGL を使う為の定義を施す。
hoge.pro
.pro はどうやら QtCreator におけるプロジェクトファイル、プロジェクトのソースコード以外のアレコレを定義するファイルらしい。この.proに
QT += opengl
を加える。どうも見るからにMakefile系のスクリプト的な感じで変数を定義しているらしい。この QT なる変数はQt系のライブラリーのリンクを制御したり、UIデザイナーでの挙動に関わっているのではないかと思う。
これでこのプロジェクトでは QGLWidget などの QtOpenGL 周りのライブラリーが使用可能になる。
ついで C++11 を使いたければ、
QMAKE_CXXFLAGS += -std=c++11
も追記しておく。
QGLWidget を実装
などして QtOpenGL による Qt の OpenGL の Widget (フォーム部品)を実装する。
"gl_widget"なるクラスを QtCreator で作成したとして進める。差し当たり次の様に OGLWidget を継承して gl_widget を実装する。
gl_widget.h
#ifndef GL_WIDGET_H #define GL_WIDGET_H #include <QtOpenGL> class gl_widget: public QGLWidget { Q_OBJECT public: gl_widget(QWidget*); protected: virtual ~gl_widget(); virtual void initializeGL(); virtual void resizeGL(int, int); virtual void paintGL(); }; #endif // GL_WIDGET_H
Q_OBJECT は Qt 関連品にはとりあえず付けておけば問題無い様だ。今回の本題でも無いので今回はとりあえず付けて置くでスルー。
includeガードがいつも#pragmaな癖にとかは今回QtCreatorの雛形からできるだけそのままにして居るので気にしないで戴きたい。
gl_widget.cpp
#include "gl_widget.h" gl_widget::gl_widget(QWidget* p = nullptr) :QGLWidget(p) {} gl_widget::~gl_widget(){} void gl_widget::initializeGL(){ glClearColor(.0, .0, .0, 1.); } void gl_widget::resizeGL(int x, int y){ glViewport(0, 0, x, y); glLoadIdentity(); auto rx = x / 200.; auto ry = y / 200.; auto z = 1; glOrtho(-rx, rx, -ry, ry, -z, z); } void gl_widget::paintGL(){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //glutWireTeapot(0.5); }
いつもは .hxx とかしてこの程度なら実装もヘッダーに詰め込む癖にー、とかも気にしないで戴きたい。あとファイル名とか。これらも基本的に今回は QtCreator の生成した雛形そのままです。
initializeGL/resizeGL/paintGL は QGLWidget に定義された仮想関数で、初期化/サイズ変更/描画のタイミングでよしなに呼ばれてくれます。素のGLの各種コールバック"的"なものですね。
paintGLで`// glutWireTeapot(0.5);`がコメントアウトしてありますが、これはまだ GLUT の準備をしていない為に使用できないからです。それでも実行すれば glClearColor で設定した色で glClear により描画タイミング毎に画面がクリアされるので動作は確認できるでしょう。
でもまだビルド&実行しても真っ黒なGLの描画画面は現れません。次にこの実装した Qt のウィジェットをフォームに組み込みます。
mainwindow.ui へ gl_widget を組み込む
mainwindow.ui を QtCreator で開くとソースではなくグラフィカルなUIデザイナーが表示されます。標準ではフォームの表示されている右側にオブジェクトをツリー表示している部分が出ているので、そこで MainWindow の中の centralWidget のコンテキストメニューを開き、 `promote to` しましょう。
Promoted class name に gl_widget と先ほど実装したQtのOpenGLウィジェットを書き込むと、自動的に Header file も gl_widget.h と入力の済んだ状態になります。 Add して Promoted Classes に表示が出たならば、ビルド&実行してみましょう。
先ほど実装した gl_widget が無事に動作すると真っ黒でクリアーするだけのGLの小窓が出ます。
GLUT ==> teapot
続いて GLUT を QtCreator のプロジェクトのお作法で準備します。
main.cpp
#include <QApplication> #include <GL/glut.h> #include "mainwindow.h" int main(int argc, char *argv[]) { glutInit(&argc, argv); QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
`GL/glut.h` のインクルードと `glutInit(&argc, argv)` を追加しました。他は QtCreator で生成した雛形のままです。