学习在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() / ;
    }
    int edges() const
    {
        return m_edgeIndices.size() / ;
    }
    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[];
    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()
        , y()
        , z()
    {
    }

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 = . / sqrt(x * x + y * y + z * z);
        return Point3d(x * r, y * r, z * r);
    }
    float &operator[](unsigned int index) {
        Q_ASSERT(index < );
        return (&x)[index];
    }

const float &operator[](unsigned int index) const {
        Q_ASSERT(index < );
        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(, ), 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(, );

return app.exec();
}

其它3D图形欣赏:

QT Graphics-View 3D编程例子- 3D Model Viewer的更多相关文章

  1. 关于QT Graphics View开启OpenGL渲染后复选框、微调框等无法正常显示的问题

    之前学习QT Graphics View框架,除了基本的图元外,还可以通过QGraphicsProxyWidget类添加QT的基本Widget(如按钮.复选框.单选框等),常使用的场景类接口如下: Q ...

  2. qt Graphics View Framework(非重点)

    Graphics View 提供了一种接口,用于管理大量自定义的 2D 图形元素,并与之进行交互:还提供了用于将这些元素进行可视化显示的观察组件,并支持缩放和旋转. 说明;Graphics View ...

  3. QT基于model/view数据库编程2

    Qt中数据编程主要分为以下两点:1.利用qt提供类 访问数据库或者成为简单的数据库编程2.数据库编程中引入model/view编程模型 基于model/view数据库编程: qt提供model类: Q ...

  4. Qt 学习之路 2(30):Graphics View Framework

    Qt 学习之路 2(30):Graphics View Framework 豆子 2012年12月11日 Qt 学习之路 2 27条评论 Graphics View 提供了一种接口,用于管理大量自定义 ...

  5. qt的应用层主要是大型3d,vr,管理软件和器械嵌入软件(有上千个下一代软件黑科技项目是qt的,美国宇航局,欧洲宇航局,超级战舰DDG1000)

    作者:Nebula.Trek链接:https://www.zhihu.com/question/24316868/answer/118944490来源:知乎著作权归作者所有.商业转载请联系作者获得授权 ...

  6. Qt 之 Graphics View Framework 简介

    Graphics View Framework 交互式 2D 图形的 Graphics View 框架概述.自 Qt4.2 中引入了 Graphics View,以取代其前身 QCanvas.Grap ...

  7. UWP简单示例(二):快速开始你的3D编程

    准备 IDE:Visual Studio 2015 了解并学习:SharpDx官方GitHub 推荐Demo:SharpDX_D3D12HelloWorld 第一节 世界 世界坐标系是一个特殊的坐标系 ...

  8. Qt 学习之路:Graphics View Framework

    Graphics View 提供了一种接口,用于管理大量自定义的 2D 图形元素,并与之进行交互:还提供了用于将这些元素进行可视化显示的观察组件,并支持缩放和旋转.我们通常所说的 Linux 的 KD ...

  9. UWP简单示例(二):快速开始你的3D编程

    准备 IDE:Visual Studio 开源库:GitHub.SharpDx 入门示例:SharpDX_D3D12HelloWorld 为什么选择 SharpDx? SharpDx 库与 UWP 兼 ...

随机推荐

  1. 多线程里面this.getName()和currentThread.getName()有什么区别

    public class hello extends Thread { public hello(){ System.out.println("Thread.currentThread(). ...

  2. 关于css的一些特别用法

    (1)input 怎么设置宽高用style来设置,<input style="width:111px;height:111px">(2)怎么让img和input在同一行 ...

  3. HBase官方文档 之 Region的相关知识

    HBase是以Region为最小的存储和负载单元(这里可不是HDFS的存储单元),因此Region的负载管理,关系到了数据读写的性能.先抛开Region如何切分不说,看看Region是如何分配到各个R ...

  4. CentOS禁止packagekit离线更新服务的办法

    以CentOs7为例,以root身份登录系统,然后执行以下命令: [root@localhost ~]# systemctl disable packagekit-offline-update.ser ...

  5. c++中几种常见的类型转换。int与string的转换,float与string的转换以及string和long类型之间的相互转换。to_string函数的实现和应用。

    1.string转换为int a.采用标准库中atoi函数,对于float和龙类型也都有相应的标准库函数,比如浮点型atof(),long型atol(). 他的主要功能是将一个字符串转化为一个数字,在 ...

  6. 在DevExpress程序中使用内置的图标构建美观的界面元素【转】

    https://www.cnblogs.com/wuhuacong/p/6217012.html 在我们一般的程序中,为一般的界面元素添加一定的图标展示,有助于提升界面的整体的美观.结合排版布局,以及 ...

  7. 出现System.web.mvc冲突的原因及解决方法CS0433

    1.问题描述 CS0433:类型“System.Web.Mvc.WebViewPage<TModel>”同时存在于URL1和URL2中 2.解决方案 找到Web.config文件中的< ...

  8. centos7下安装gcc7

    之前写过在linux下升级gcc 4.8至gcc 4.9的过程,现在gcc最新的版本是8,有些软件必须是gcc 7或者以上的版本才可以编译,比如clickhouse,gcc 7的安装过程和之前基本上一 ...

  9. Android官方导航栏ActionBar(二)—— Action View、Action Provider、Navigation Tabs的详细用法

    在上一篇文章(Android之官方导航栏ActionBar)中,我们介绍了ActionBar各组成部分的基本应用.ActionBar除了提供Action Buttons外,还提供了多种导航方式如 Ac ...

  10. (转)Unity3D - 动作动画忽略timeScale

    转自:http://blog.csdn.net/ynnmnm/article/details/46866347 最近在调战斗时的动画与特效,Unity3D对加/减速提供了Time.timeScale支 ...