45.Qt openGL實現三維繪圖
阿新 • • 發佈:2018-05-13
窗口 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> classTetrahedron : 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); voidmouseMoveEvent(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實現三維繪圖