bambooflow Note

テクスチャマッピング

最終更新:

bambooflow

- view
メンバー限定 登録/ログイン

QtでOpenGL:テクスチャマッピング



概要


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)内には
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 OpenGL
記事メニュー
ウィキ募集バナー