學習在Graphics-View框架中使用opengl進行3D編程,在網上找了一個不錯的例子“3D Model Viewer”,很值得學習。
可以在http://www.oyonale.com/accueil.php?lang=en上下載一些3D模型來測試!
先來一張該例子的截圖,看下效果:
該例子使用Graphics-View框架,繪制一個表示太陽的圖元(item);
並在窗口的左上角區域放置了一個2D Widget控制以及說明面板(可以加載不同的3D模型,改變顏色,網格、法向量顯示等!);
通過加載obj模型文件,使用opengl在背景層繪制3D圖形,並可以使用鼠標進行控制,但是一次性只能加載一個3D圖形。
相關代碼如下:
Model.h - 用於從obj文件中加載3D圖形
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
/**************************************************************************** ** ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the documentation of Qt. It was originally ** published as part of Qt Quarterly. ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License versions 2.0 or 3.0 as published by the Free ** Software Foundation and appearing in the file LICENSE.GPL included in ** the packaging of this file. Please review the following information ** to ensure GNU General Public Licensing requirements will be met: ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and ** http://www.gnu.org/copyleft/gpl.html. In addition, as a special ** exception, Nokia gives you certain additional rights. These rights ** are described in the Nokia Qt GPL Exception version 1.3, included in ** the file GPL_EXCEPTION.txt in this package. ** ** Qt for Windows(R) Licensees ** As a special exception, Nokia, as the sole copyright holder for Qt ** Designer, grants users of the Qt/Eclipse Integration plug-in the ** right for the Qt/Eclipse Integration to link to functionality ** provided by Qt Designer and its related libraries. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #ifndef MODEL_H #define MODEL_H #include <QString> #include <QVector> #include <math.h> #include "point3d.h" class Model { public : Model() {} Model( const QString &filePath); void render( bool wireframe = false , bool normals = false ) const ; QString fileName() const { return m_fileName; } int faces() const { return m_pointIndices.size() / 3 ; } int edges() const { return m_edgeIndices.size() / 2 ; } int points() const { return m_points.size(); } private : QString m_fileName; QVector<Point3d> m_points; QVector<Point3d> m_normals; QVector< int > m_edgeIndices; QVector< int > m_pointIndices; }; #endif |
OpenGLScene.h - 使用了opengl渲染的場景
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
/**************************************************************************** ** ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the documentation of Qt. It was originally ** published as part of Qt Quarterly. ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License versions 2.0 or 3.0 as published by the Free ** Software Foundation and appearing in the file LICENSE.GPL included in ** the packaging of this file. Please review the following information ** to ensure GNU General Public Licensing requirements will be met: ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and ** http://www.gnu.org/copyleft/gpl.html. In addition, as a special ** exception, Nokia gives you certain additional rights. These rights ** are described in the Nokia Qt GPL Exception version 1.3, included in ** the file GPL_EXCEPTION.txt in this package. ** ** Qt for Windows(R) Licensees ** As a special exception, Nokia, as the sole copyright holder for Qt ** Designer, grants users of the Qt/Eclipse Integration plug-in the ** right for the Qt/Eclipse Integration to link to functionality ** provided by Qt Designer and its related libraries. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #ifndef OPENGLSCENE_H #define OPENGLSCENE_H #include "point3d.h" #include <QGraphicsScene> #include <QLabel> #include <QTime> #ifndef QT_NO_CONCURRENT #include <QFutureWatcher> #endif class Model; class OpenGLScene : public QGraphicsScene { Q_OBJECT public : OpenGLScene(); void drawBackground(QPainter *painter, const QRectF &rect); void drawForeground(QPainter *painter, const QRectF &rect); public slots: void enableWireframe( bool enabled); void enableNormals( bool enabled); void setModelColor(); void setBackgroundColor(); void loadModel(); void loadModel( const QString &filePath); void modelLoaded(); protected : void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void wheelEvent(QGraphicsSceneWheelEvent * wheelEvent); private : QDialog *createDialog( const QString &windowTitle) const ; void setModel(Model *model); bool m_wireframeEnabled; bool m_normalsEnabled; QColor m_modelColor; QColor m_backgroundColor; Model *m_model; QTime m_time; int m_lastTime; int m_mouseEventTime; float m_distance; Point3d m_rotation; Point3d m_angularMomentum; Point3d m_accumulatedMomentum; QLabel *m_labels[ 4 ]; QWidget *m_modelButton; QGraphicsRectItem *m_lightItem; #ifndef QT_NO_CONCURRENT QFutureWatcher<Model *> m_modelLoader; #endif }; #endif |
Point3d.h - 描述3D點數據的一個類
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
/**************************************************************************** ** ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the documentation of Qt. It was originally ** published as part of Qt Quarterly. ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License versions 2.0 or 3.0 as published by the Free ** Software Foundation and appearing in the file LICENSE.GPL included in ** the packaging of this file. Please review the following information ** to ensure GNU General Public Licensing requirements will be met: ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and ** http://www.gnu.org/copyleft/gpl.html. In addition, as a special ** exception, Nokia gives you certain additional rights. These rights ** are described in the Nokia Qt GPL Exception version 1.3, included in ** the file GPL_EXCEPTION.txt in this package. ** ** Qt for Windows(R) Licensees ** As a special exception, Nokia, as the sole copyright holder for Qt ** Designer, grants users of the Qt/Eclipse Integration plug-in the ** right for the Qt/Eclipse Integration to link to functionality ** provided by Qt Designer and its related libraries. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #ifndef POINT3D_H #define POINT3D_H #include "math.h" #include <qglobal.h> struct Point3d { float x, y, z; Point3d() : x( 0 ) , y( 0 ) , z( 0 ) { } Point3d( float x_, float y_, float z_) : x(x_) , y(y_) , z(z_) { } Point3d operator +( const Point3d &p) const { return Point3d(* this ) += p; } Point3d operator -( const Point3d &p) const { return Point3d(* this ) -= p; } Point3d operator *( float f) const { return Point3d(* this ) *= f; } Point3d & operator +=( const Point3d &p) { x += p.x; y += p.y; z += p.z; return * this ; } Point3d & operator -=( const Point3d &p) { x -= p.x; y -= p.y; z -= p.z; return * this ; } Point3d & operator *=( float f) { x *= f; y *= f; z *= f; return * this ; } Point3d normalize() const { float r = 1 . / sqrt(x * x + y * y + z * z); return Point3d(x * r, y * r, z * r); } float & operator []( unsigned int index) { Q_ASSERT(index < 3 ); return (&x)[index]; } const float & operator []( unsigned int index) const { Q_ASSERT(index < 3 ); return (&x)[index]; } }; inline float dot( const Point3d &a, const Point3d &b) { return a.x * b.x + a.y * b.y + a.z * b.z; } inline Point3d cross( const Point3d &a, const Point3d &b) { return Point3d(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } #endif |
主函數調用:
main.cpp
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#include
"openglscene.h"
#include <QApplication> #include <QObject> #include <QGLWidget> #include <QGraphicsView> #include <QResizeEvent> class GraphicsView : public QGraphicsView { public : GraphicsView() { setWindowTitle(tr( "3D Model Viewer" )); } protected : void resizeEvent(QResizeEvent *event) { if (scene()) scene()->setSceneRect(QRect(QPoint( 0 , 0 ), event->size())); QGraphicsView::resizeEvent(event); } }; int main( int argc, char **argv) { QApplication app(argc, argv); GraphicsView view; view.setViewport( new QGLWidget(QGLFormat(QGL::SampleBuffers))); view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate); view.setScene( new OpenGLScene); view.show(); view.resize( 1024 , 768 ); return app.exec(); } |
其它3D圖形欣賞: