zoukankan      html  css  js  c++  java
  • 45.Qt openGL实现三维绘图

    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];
    }
  • 相关阅读:
    The formatter threw an exception while trying to deserialize the message in WCF
    通过Web Deploy方式部署WCF
    The Managed Metadata Service or Connection is currently not available
    How to create Managed Metadata Column
    冒泡算法
    asp.net core 实战项目(一)——ef core的使用
    Vue学习笔记入门篇——安装及常用指令介绍
    Vue学习笔记入门篇——数据及DOM
    Vue学习笔记目录
    Chart.js在Laravel项目中的应用
  • 原文地址:https://www.cnblogs.com/xiaochi/p/9032963.html
Copyright © 2011-2022 走看看