2010年4月7日水曜日

Qt4 で 「手抜き」OpenGL入門


前回、UbuntuでOpenGLとQtの環境を作ることを説明した続きです。

まず、OpenGLの一番有名な床井先生の入門サイトの紹介です

GLUTによる「手抜き」OpenGL入門 和歌山大学 システム工学部 デザイン情報学科 床井浩平

このサイトではGLUTを使ったサンプルや説明がされています。OpenGLの説明自体は前述のサイトを参照していただくとして、今回はこのサイトで取り上げられているサンプルを、GLUTではなく、Qt4のQGLWidgetで実装してみます。ソースコードは下記です。


http://svn.xp-dev.com/svn/algos/algos3d/qt4sample/sample02/


コンパイルと実効は下記です

----------------
make
./sample02

----------------

実行するとQtの画面上でキューブが回転します。今回はQGLWidgetとQThreadを使います。
OpenGLのバッファの制御はQGLWidgetを使っています。ただし、これだけだとアニメーション処理ができないので、QThreadクラスを使って連続描画を行っています。

GLUTはWindowsに持っていった時に終了イベントがとれなかったり、UIも日本語対応が甘かったり意外と融通が効かないので、Qtベースでの実装も試してみると良い事があるかもしれません。


MyGLWidget.h
----------------------------

#include "qapplication.h"
#include "qthread.h"
#include "qgl.h"

#ifndef MYGLWIDGET_H_
#define MYGLWIDGET_H_

class MyGLWidget : public QGLWidget, public QThread
{
Q_OBJECT;
public:
MyGLWidget();
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void run();
double r;
};

#endif /* MYGLWIDGET_H_ */

MyGLWidget.cpp
----------------------------
#include "MyGLWidget.h"

MyGLWidget::MyGLWidget()
{
QThread::start();
}

void MyGLWidget::initializeGL()
{
glEnable(GL_DEPTH_TEST);
glClearColor( 1.0, 1.0, 1.0, 1.0 );
}

void MyGLWidget::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}

void MyGLWidget::paintGL()
{
GLdouble vertex[][3] = {
{ 0.0, 0.0, 0.0 }, /* A */
{ 1.0, 0.0, 0.0 }, /* B */
{ 1.0, 1.0, 0.0 }, /* C */
{ 0.0, 1.0, 0.0 }, /* D */
{ 0.0, 0.0, 1.0 }, /* E */
{ 1.0, 0.0, 1.0 }, /* F */
{ 1.0, 1.0, 1.0 }, /* G */
{ 0.0, 1.0, 1.0 } /* H */
};

int face[][4] = {
{ 0, 1, 2, 3 },
{ 1, 5, 6, 2 },
{ 5, 4, 7, 6 },
{ 4, 0, 3, 7 },
{ 4, 5, 1, 0 },
{ 3, 2, 6, 7 }
};
GLdouble color[][3] = {
{ 1.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 1.0 },
{ 1.0, 1.0, 0.0 },
{ 1.0, 0.0, 1.0 },
{ 0.0, 1.0, 1.0 }
};

int i,j;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

if(r>360)r=0;
glRotated(r, 0.0, 1.0, 0.0);
glRotated(r+=2, 1.0, 1.0, 0.0);

glBegin(GL_QUADS);
for (j = 0; j < 6; ++j) {
glColor3dv(color[j]);
for (i = 0; i < 4; ++i) {
glVertex3dv(vertex[face[j][i]]);
}
}
glEnd();
}

void MyGLWidget::run()
{
while(1){
QThread::usleep(10000);
update();
}
}

0 件のコメント:

コメントを投稿