QT Graphics-View 3D編程例子- 3D Model Viewer


學習在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圖形欣賞:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM