QtでOpenGL:テクスチャマッピング
概要
Qtでのテクスチャマッピングは、簡単です。
Qtは標準クラスで画像を読み込むクラスを持っています。
また、併せてテクスチャをバインドする専用をメソッドを使うことで、テクスチャマッピングの手続きが簡略化することができます。
Qtは標準クラスで画像を読み込むクラスを持っています。
また、併せてテクスチャをバインドする専用をメソッドを使うことで、テクスチャマッピングの手続きが簡略化することができます。
通常の手続きだと、
画像の読み込み ↓ glGenTextures(GL_TEXTURE_2D, &texture); ↓ glBindTexture(GL_TEXTURE_2D, texture); ↓ glTexImage2D( .. );
となり、面倒です。
これがQtだと、
texture = bindTexture(QImage(":/image.jpg", GL_TEXTURE_2D));
なんと1つのメソッドでできてしまいます。
Qtでは、画像を扱うにあたってリソースを追加する作業が発生します。
以下にその方法を記載しますが、手順はそれほど難しくありません。
以下にその方法を記載しますが、手順はそれほど難しくありません。
画像をリソースに追加する手順
Qt Creatorの操作方法について説明します。
メニュの
- ファイル→ファイル/プロジェクトの新規作成
を選択します。
- Qt→Qtリソースファイル
を選択します。

- 名前をここでは"textures"とします
- 「次へ」をクリックします。

- そのまま「完了」をクリックします

- 「追加」をクリックし、「プレフィックス」を"/"とします
- さらに「追加」をクリックし、「ファイルの追加」でここでは"image.jpg"を選択します

これで、画像がリソースとして追加されました。
追加が完了すると、
追加が完了すると、
- textures.qrc
というリソースファイルが作成されます。
また、プロジェクト(.pro)内には
また、プロジェクト(.pro)内には
RESOURCES += \ textures.qrc
と追加されます。
ソースコード
- glwidget.h
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QBasicTimer>
#include <QGLWidget>
class GLWidget : public QGLWidget
{
Q_OBJECT
public:
GLWidget(QWidget *parent = 0);
~GLWidget();
protected:
void timerEvent(QTimerEvent *e);
protected:
virtual void initializeGL();
virtual void resizeGL( int w, int h );
virtual void paintGL();
private:
QBasicTimer *timer;
private:
GLfloat angle;
GLuint texture;
};
#endif // GLWIDGET_H
- glwidget.cpp
#include "glwidget.h"
GLWidget::GLWidget(QWidget *parent):
DrawStuff(parent),
timer(new QBasicTimer)
{
}
GLWidget::~GLWidget()
{
glDeleteTextures(1, &texture);
delete timer; timer = 0;
}
void GLWidget::timerEvent(QTimerEvent *e)
{
Q_UNUSED(e);
updateGL();
}
void GLWidget::initializeGL()
{
glClearColor(0.5, 0.5, 0.5, 1.0);
glEnable(GL_DEPTH_TEST);
//カリング:表面のみ表示
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
//光源有効
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//光源の設定
GLfloat light_position[] = { -50.0, 50.0, 50.0, 1.0 };
GLfloat light_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv( GL_LIGHT0, GL_POSITION, light_position );
glLightfv( GL_LIGHT0, GL_AMBIENT, light_ambient );
glLightfv( GL_LIGHT0, GL_DIFFUSE, light_diffuse );
glLightfv( GL_LIGHT0, GL_SPECULAR, light_specular );
//テクスチャ 初期化
texture = bindTexture(QImage(":/image.jpg"));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
timer->start(16, this);
}
void GLWidget::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);
}
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//モデル・ビュー・マトリックス設定
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
//カメラ設定
gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
{ // 平面表示
//材質設定
//GLfloat color[] = { 0.8, 0.2, 0.2, 1.0 };
GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
glRotatef(angle, 0.0, 1.0, 0.0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glNormal3f(0.0, 1.0, 0.0);
glTexCoord2f(2.0, 0.0); glVertex3f(-1.0, 0.0, -1.0);
glTexCoord2f(2.0, 2.0); glVertex3f(-1.0, 0.0, 1.0);
glTexCoord2f(0.0, 2.0); glVertex3f( 1.0, 0.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, 0.0, -1.0);
glEnd();
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
glPopMatrix();
angle = (angle>360.0) ? angle-360.0 : angle+1;
}
まとめ
Qtを使うことでテクスチャマッピングがかなりハードルが下がった感じがします。
面倒な画像読み込み処理がなくなったことが大きいです。
ただ、Qtを使いこなすまでのハードルが高いですが。。。
面倒な画像読み込み処理がなくなったことが大きいです。
ただ、Qtを使いこなすまでのハードルが高いですが。。。