Qt_OpenGL:3D旋轉自定義換色

Qt_OpenGL:3D旋轉自定義換色

//.h

#ifndef ROTATEWIDGET_H
#define ROTATEWIDGET_H

#include <QMainWindow>
#include <QtOpenGL/QtOpenGL>

class RotateWidget : public QGLWidget
{
    Q_OBJECT

public:
    RotateWidget(QWidget *parent = 0);
    ~RotateWidget();
protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int width, int height);
    void mousePressEvent(QMouseEvent*);
    void mouseMoveEvent(QMouseEvent*);
    void mouseDoubleClickEvent(QMouseEvent*);
    void mouseReleaseEvent(QMouseEvent *);
private slots:
    void Rotate();
private:
    void draw();
    int faceAtPosition(const QPoint &pos);
    void Spin(int xAngle, int yAngle, int zAngle);
private:
    QTimer *timer;
    GLfloat rotationX;
    GLfloat rotationY;
    GLfloat rotationZ;
    QColor faceColors[6];
    QPoint lastPos;

};

#endif // ROTATEWIDGET_H

//.cpp

#include "rotatewidget.h"
#include <glut.h>
#include <QTimer>

RotateWidget::RotateWidget(QWidget *parent)
    : QGLWidget(parent)
{
    setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));

    rotationX = -21.0;
    rotationY = -57.0;
    rotationZ = 0.0;

    faceColors[0] = Qt::red;
    faceColors[1] = Qt::green;
    faceColors[2] = Qt::blue;
    faceColors[3] = Qt::yellow;
    faceColors[4] = Qt::gray;
    faceColors[5] = Qt::cyan;

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(Rotate()));
    timer->start(20);

}

void RotateWidget::initializeGL(){

    qglClearColor(Qt::black);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
}

void RotateWidget::resizeGL(int width, int height){

    glViewport(0,0,width,height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    GLfloat x = GLfloat(width) / height;
    glFrustum(-x,x,-1.0,1.0,4.0,15.0);
    glMatrixMode(GL_MODELVIEW);
}

void RotateWidget::paintGL(){

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    draw();
}

void RotateWidget::draw(){

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0,0.0,-10.0);
    glRotatef(rotationX/16.0f, 1.0, 0.0, 0.0);
    glRotatef(rotationY/16.0f, 0.0, 1.0, 0.0);
    glRotatef(rotationZ/16.0f, 0.0, 0.0, 1.0);

    glBegin(GL_QUADS);  //繪製立方體
    glColor3f(faceColors[0].redF(),faceColors[0].greenF(),faceColors[0].blueF());
    glVertex3f( 1.0f, 1.0f,-1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f);

    glColor3f(faceColors[1].redF(),faceColors[1].greenF(),faceColors[1].blueF());
    glVertex3f( 1.0f,-1.0f, 1.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f);

    glColor3f(faceColors[2].redF(),faceColors[2].greenF(),faceColors[2].blueF());
    glVertex3f( 1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f);

    glColor3f(faceColors[3].redF(),faceColors[3].greenF(),faceColors[3].blueF());
    glVertex3f( 1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f( 1.0f, 1.0f,-1.0f);

    glColor3f(faceColors[4].redF(),faceColors[4].greenF(),faceColors[4].blueF());
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);

    glColor3f(faceColors[5].redF(),faceColors[5].greenF(),faceColors[5].blueF());
    glVertex3f( 1.0f, 1.0f,-1.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f);
    glEnd();

}

void RotateWidget::mousePressEvent(QMouseEvent *event){

    lastPos = event->pos();
}

void RotateWidget::mouseMoveEvent(QMouseEvent *event){

    GLfloat dx = GLfloat(event->x() - lastPos.x()) / width();
    GLfloat dy = GLfloat(event->y() - lastPos.y()) / height();
    if(event->buttons() & Qt::LeftButton){
        rotationX += 360 * dx;
        rotationY += 360 * dy;
        rotationZ += 360 * dx;
        timer->stop();
        updateGL();
    }else if(event->buttons() & Qt::RightButton){
        rotationX += 360 * dy;
        rotationZ += 360 * dx;
        timer->stop();
        updateGL();
    }
    lastPos = event->pos();
}

void RotateWidget::mouseDoubleClickEvent(QMouseEvent *event){

    int face = faceAtPosition(event->pos());
    if(face != -1){
        QColor color = QColorDialog::getColor(faceColors[face],this);
        if(color.isValid()){
            faceColors[face] = color;
            updateGL();
        }
    }
}

void RotateWidget::mouseReleaseEvent(QMouseEvent *event){

    timer->start(20);
}

int RotateWidget::faceAtPosition(const QPoint &pos){

    const int MaxSize = 512;
    GLuint buffer[MaxSize];
    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);
    glSelectBuffer(MaxSize, buffer);
    glRenderMode(GL_SELECT);
    glInitNames();
    glPushName(0);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluPickMatrix(GLdouble(pos.x()), GLdouble(viewport[3] - pos.y()),
            5.0, 5.0, viewport);
    GLfloat x = GLfloat(width()) / height();
    glFrustum(-x, x, -1.0, 1.0, 4.0, 15.0);
    draw();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    if (!glRenderMode(GL_RENDER))
        return -1;
    return buffer[3];

}

void RotateWidget::Rotate(){

    this->Spin(+2*16, +2*16, -1*16);
}

void RotateWidget::Spin(int xAngle, int yAngle, int zAngle){

    rotationX += xAngle;
    rotationY += yAngle;
    rotationZ += zAngle;
    updateGL();
}

RotateWidget::~RotateWidget()
{
    if(timer){
        delete(timer);
    }
}

//main.cpp

#include "rotatewidget.h"
#include <QApplication>
#include <iostream>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    if(!QGLFormat::hasOpenGL()){
        std::cerr << "This system has no OpenGL support..." << endl;
        return 1;
    }
    RotateWidget w;
    w.setWindowTitle(QObject::tr("OpenGL on Qt Rotation test"));
    w.resize(300,300);
    w.show();
    return a.exec();
}

運行結果截圖:


換色後:




發佈了207 篇原創文章 · 獲贊 34 · 訪問量 55萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章