1. 程式人生 > >45.Qt openGL實現三維繪圖

45.Qt openGL實現三維繪圖

窗口 err lin span protected 調用 event header 實現

技術分享圖片

main.cpp

#include <QApplication>
#include <iostream>

#include "tetraheadron.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    if (!QGLFormat::hasOpenGL()) {
        std::cerr << "This system has no OpenGL support" << std::endl;
        
return 1; } Tetrahedron tetrahedron; tetrahedron.setWindowTitle(QObject::tr("Tetrahedron")); tetrahedron.resize(300, 300); tetrahedron.show(); return app.exec(); }

tetraheaderon.h

#ifndef TETRAHEDRON_H
#define TETRAHEDRON_H

#include <QGLWidget>

class
Tetrahedron : public QGLWidget { Q_OBJECT public: Tetrahedron(QWidget *parent = 0); protected: //在QGLWidget中實現 void initializeGL(); void resizeGL(int width, int height); void paintGL(); //鼠標事件處理在QWidget中實現 void mousePressEvent(QMouseEvent *event); void
mouseMoveEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent *event); private: void draw(); int faceAtPosition(const QPoint &pos); GLfloat rotationX; GLfloat rotationY; GLfloat rotationZ; QColor faceColors[4]; QPoint lastPos; }; #endif

tetraheadron.cpp

#include <QtGui>
#include <QtOpenGL>
#include <GL/glu.h>
#include "tetraheadron.h"

Tetrahedron::Tetrahedron(QWidget *parent)
    : QGLWidget(parent)
{
    //指定OpenGL的顯示描述表
    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;
}

//在調用paintGL()之前被調用一次.這裏設置
//OpenGL的繪圖描述表,定義顯示列表,以及執行其他的初始化
void Tetrahedron::initializeGL()
{
    qglClearColor(Qt::black);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
}

//調用initializeGL之後調用resizeGL()函數,窗口部件改變大小時也調用resizeGL()
//函數,設置OpenGL視口,投影,以及其他與窗口部件尺寸相關的設置
void Tetrahedron::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 Tetrahedron::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //實際的繪制由私有函數draw()實現
    draw();
}

//鼠標按下的事件
void Tetrahedron::mousePressEvent(QMouseEvent *event)
{
    lastPos = event->pos();
}

//鼠標移動的事件
void Tetrahedron::mouseMoveEvent(QMouseEvent *event)
{
    GLfloat dx = GLfloat(event->x() - lastPos.x()) / width();
    GLfloat dy = GLfloat(event->y() - lastPos.y()) / height();

    //左鍵繞X,Y軸
    if (event->buttons() & Qt::LeftButton) {
        rotationX += 180 * dy;
        rotationY += 180 * dx;
        updateGL();
    }
    //右鍵繞X,Z軸
    else if (event->buttons() & Qt::RightButton) {
        rotationX += 180 * dy;
        rotationZ += 180 * dx;
        updateGL();
    }
    lastPos = event->pos();
}

//雙擊事件
void Tetrahedron::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 Tetrahedron::draw()
{
    static const GLfloat P1[3] = { 0.0, -1.0, +2.0 };
    static const GLfloat P2[3] = { +1.73205081, -1.0, -1.0 };
    static const GLfloat P3[3] = { -1.73205081, -1.0, -1.0 };
    static const GLfloat P4[3] = { 0.0, +2.0, 0.0 };

    //四個面
    static const GLfloat * const coords[4][3] = {
        { P1, P2, P3 }, { P1, P3, P4 }, { P1, P4, P2 }, { P2, P4, P3 }
    };

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -10.0);
    //設置旋轉
    glRotatef(rotationX, 1.0, 0.0, 0.0);
    glRotatef(rotationY, 0.0, 1.0, 0.0);
    glRotatef(rotationZ, 0.0, 0.0, 1.0);

    //設置顏色
    for (int i = 0; i < 4; ++i) {
        glLoadName(i);
        glBegin(GL_TRIANGLES);
        qglColor(faceColors[i]);
        for (int j = 0; j < 3; ++j) {
            glVertex3f(coords[i][j][0], coords[i][j][1],
                       coords[i][j][2]);
        }
        glEnd();
    }
}

//返回窗口部件某位置所在的面的編號
int Tetrahedron::faceAtPosition(const QPoint &pos)
{
    const int MaxSize = 512;
    GLuint buffer[MaxSize];
    GLint viewport[4];

    makeCurrent();

    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];
}

45.Qt openGL實現三維繪圖