bambooflow Note

タイマーを使ったアニメーション

最終更新:

bambooflow

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

QtでOpenGL:タイマーを使ったアニメーション





概要


QGLWidgetのpaintGL()はupdateGL()がシグナルとなって呼ばれます。
ここではタイマーを使って一定間隔ごとにupdateGL()を呼ぶことでアニメーションさせます。
タイマーは、QBasicTimerクラスを用います。


使い方は下記の通りです。
#include <QBasicTimer>
 
  QBasicTimer timer;
 
void GLWidget::initializeGL()
{
  //タイマーの開始、間隔を16ms(≒60fps)に設定
  timer.start(16, this);
}
 
void GLWidget::timerEvent(QTimerEvent *e)
{
    Q_UNUSED(e);
    updateGL();
}
 

このとき、timer.startの第一引数がタイマーの間隔で、第二引数がtimerEventメソッドを持つオブジェクトを渡します。
ここではGLWidgetのメソッドとしてtiemrEventを用意しているので、第二引数はthisとします。



ソースコード


  • glwidget.h
#ifndef GLWIDGET_H
#define GLWIDGET_H
 
#include <QGLWidget>
#include <QVector3D>
#include <QBasicTimer>
 
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();
 
    GLuint createCube();
 
private:
    QBasicTimer *timer;
 
private:
    GLfloat angle;
    GLuint cubeList;
};
 
#endif // GLWIDGET_H
 


  • glwidget.cpp
#include "glwidget.h"
#include <math.h>
 
GLWidget::GLWidget(QWidget *parent):
  QGLWidget(parent),
  timer(new QBasicTimer)
{
}
 
GLWidget::~GLWidget()
{
    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 );
 
    cubeList = createCube();
 
    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 red[] = { 0.8, 0.2, 0.2, 1.0 };
        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
 
        glRotatef(angle, 0.0, 1.0, 0.0); // 回転
        //glCallList(cubeList);
        glCallList(sphereList);
    }
    glPopMatrix();
 
    angle = (angle>360.0) ? angle-360.0 : angle+1;
}
 
GLuint GLWidget::createCube()
{
    GLuint index = glGenLists(1);
 
    float lx = 0.5f;
    float ly = 0.5f;
    float lz = 0.5f;
 
    glNewList(index, GL_COMPILE);
 
    // sides
    glBegin (GL_TRIANGLE_STRIP);
    glNormal3f (-1,0,0);
    glVertex3f (-lx,-ly,-lz);
    glVertex3f (-lx,-ly,lz);
    glVertex3f (-lx,ly,-lz);
    glVertex3f (-lx,ly,lz);
    glNormal3f (0,1,0);
    glVertex3f (lx,ly,-lz);
    glVertex3f (lx,ly,lz);
    glNormal3f (1,0,0);
    glVertex3f (lx,-ly,-lz);
    glVertex3f (lx,-ly,lz);
    glNormal3f (0,-1,0);
    glVertex3f (-lx,-ly,-lz);
    glVertex3f (-lx,-ly,lz);
    glEnd();
 
    // top face
    glBegin (GL_TRIANGLE_FAN);
    glNormal3f (0,0,1);
    glVertex3f (-lx,-ly,lz);
    glVertex3f (lx,-ly,lz);
    glVertex3f (lx,ly,lz);
    glVertex3f (-lx,ly,lz);
    glEnd();
 
    // bottom face
    glBegin (GL_TRIANGLE_FAN);
    glNormal3f (0,0,-1);
    glVertex3f (-lx,-ly,-lz);
    glVertex3f (-lx,ly,-lz);
    glVertex3f (lx,ly,-lz);
    glVertex3f (lx,-ly,-lz);
    glEnd();
 
    glEndList();
 
    return index;
}
 

タグ:

Qt OpenGL
記事メニュー
目安箱バナー