首页 > 其他分享 >Qt绘制3D图形例程

Qt绘制3D图形例程

时间:2023-09-01 18:03:22浏览次数:51  
标签:0.8 1.0 Qt 例程 0.0 void int program 3D

本文主要内容是关于QOpenGLWidget的使用。此控件用于代替旧的QGLWidget类。关于此类的使用方法可以参考Qt帮助相关内容。

下面将从简到繁给出3个例子带读者入门Qt3D的世界。以下代码开发平台是VS2017和Qt5.9。

一、绘制曲面和颜色

本代码实现了一个沿着x轴旋转的彩色曲面。头文件:

class QOpenGLShaderProgram;

//---------------------------------------------------------------------------------------
// 显示彩虹色
//---------------------------------------------------------------------------------------
class MyOpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions
{
    Q_OBJECT

public:
    MyOpenGLWidget(QWidget* parent = 0);

private:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;

private:
    QOpenGLShaderProgram* program;
    int iter;
};

CPP文件:

MyOpenGLWidget::MyOpenGLWidget(QWidget* parent) :
    QOpenGLWidget(parent), iter(0)
{
    QSurfaceFormat surface;
    surface.setSamples(4);
    setFormat(surface);

    QTimer* timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, QOverload<>::of(&MyOpenGLWidget::update));
    timer->setInterval(100);
    timer->start();
}

void MyOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glEnable(GL_DEPTH_TEST);

    QOpenGLShader* vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char* vsrc = R"(
        in vec4 vposition;
        in vec4 vcolor;
        out vec4 ocolor;
        uniform mat4 trans;
        void main() {
            gl_Position = trans * vposition;
            ocolor = vcolor;
        })";
    vshader->compileSourceCode(vsrc);
    QOpenGLShader* fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char* fsrc = R"(
        in vec4 ocolor;
        void main() {
            gl_FragColor = ocolor;
        })";
    fshader->compileSourceCode(fsrc);

    program = new QOpenGLShaderProgram(this);
    program->addShader(vshader);
    program->addShader(fshader);
    program->link();
    program->bind();

    delete vshader;
    delete fshader;
}

void MyOpenGLWidget::paintGL()
{
    GLfloat vertices[] =
    {
        -0.8f, 0.8f, 0.2f,
        -0.8f, -0.8f, -0.3f,
        0.8f, 0.8f, 0.0f,
        0.8f, -0.8f, 0.5f,
    };
    GLfloat colors[] =
    {
        0.9f, 0.7f, 0.1f,
        0.2f, 0.7f, 0.3f,
        0.8f, 0.0f, 0.5f,
        0.1f, 0.1f, 0.9f,
    };
    
    QMatrix4x4 matrix;
    matrix.perspective(60.0f, 1.0f, 1.0f, 100.0f);
    matrix.translate(0, 0, -3);
    matrix.rotate(iter * 1.0f, 1, 0, 0);
    program->setUniformValue("trans", matrix);
    program->enableAttributeArray("trans");
    iter++;

    program->setAttributeArray("vposition", vertices, 3);
    program->enableAttributeArray("vposition");
    program->setAttributeArray("vcolor", colors, 3);
    program->enableAttributeArray("vcolor");
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

void MyOpenGLWidget::resizeGL(int w, int h)
{
}

程序运行效果如下图:

二、绘制曲面和贴图

本代码实现了一个沿着z轴旋转的曲面,曲面上贴了图片。头文件:

class QOpenGLTexture;

//---------------------------------------------------------------------------------------
// 显示图片
//---------------------------------------------------------------------------------------
class MzOpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions
{
    Q_OBJECT

public:
    MzOpenGLWidget(QWidget* parent = 0);

private:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;

private:
    QOpenGLShaderProgram* program;
    QOpenGLTexture *texture;
    int iter;
};

CPP文件:

MzOpenGLWidget::MzOpenGLWidget(QWidget* parent) :
    QOpenGLWidget(parent), iter(0)
{
    QSurfaceFormat surface;
    surface.setSamples(4);
    setFormat(surface);

    QTimer* timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, QOverload<>::of(&MyOpenGLWidget::update));
    timer->setInterval(100);
    timer->start();
}

void MzOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glEnable(GL_DEPTH_TEST);

    program = new QOpenGLShaderProgram(this);
    const char* vsrc = R"(
        in vec4 pos;
        in vec2 itextCoor;
        out vec2 otextCoor;
        uniform mat4 trans;
        void main() {
            gl_Position = trans * pos;
            otextCoor = itextCoor;
        })";
    program->addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc);
    const char* fsrc = R"(
        uniform sampler2D image;
        in vec2 otextCoor;
        void main() {
            gl_FragColor = texture2D(image, otextCoor);
        })";
    program->addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc);

    texture = new QOpenGLTexture(QImage(u8"F:/Mr.Duu/ProjectM/QtTest/QtTest/1.bmp"));
    texture->setMinificationFilter(QOpenGLTexture::LinearMipMapNearest); /* 缩小图片插值方法 */
    texture->setMagnificationFilter(QOpenGLTexture::LinearMipMapLinear); /* 放大图片插值方法 */
    texture->setWrapMode(QOpenGLTexture::Repeat);

    program->link();
    program->bind();
}

void MzOpenGLWidget::paintGL()
{
    GLfloat vertices[] =
    {
        -0.8f, 0.8f, 0.2f, 
        -0.8f, -0.8f, -0.3f, 
        0.8f, 0.8f, 0.0f, 
        0.8f, -0.8f, 0.5f, 
    };
    GLfloat coors[] = /* 此数组和vertices数组一一对应 */
    {
        0.0f, 0.0f,
        0.0f, 2.2f, 
        2.2f, 0.0f,
        2.2f, 2.2f,
    };
    
    QMatrix4x4 matrix;
    matrix.perspective(60.0f, 1.0f, 1.0f, 100.0f);
    matrix.translate(0, 0, -3);
    matrix.rotate(iter * 1.0f, 0, 1, 0);
    program->setUniformValue("trans", matrix);
    program->enableAttributeArray("trans");
    iter++;

    program->setAttributeArray("pos", vertices, 3);
    program->enableAttributeArray("pos");
    program->setAttributeArray("itextCoor", coors, 2);
    program->enableAttributeArray("itextCoor");
    program->setUniformValue("image", 0);
    texture->bind(0);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

void MzOpenGLWidget::resizeGL(int w, int h)
{
}

程序运行效果如下:

三、绘制立体图形和颜色

立体图形其实也是曲面,只不过首尾点相同把曲面连接成了封闭的图形。下面给出一个绘制三棱锥的例子。头文件:

class QOpenGLTexture;

//---------------------------------------------------------------------------------------
// 显示图片
//---------------------------------------------------------------------------------------
class MxOpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions
{
    Q_OBJECT

public:
    MxOpenGLWidget(QWidget* parent = 0);

private:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;

private:
    QOpenGLShaderProgram* program;
    int iter;
};

CPP文件:

MxOpenGLWidget::MxOpenGLWidget(QWidget* parent) :
    QOpenGLWidget(parent), iter(0)
{
    QSurfaceFormat surface;
    surface.setSamples(4);
    setFormat(surface);

    QTimer* timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, QOverload<>::of(&MyOpenGLWidget::update));
    timer->setInterval(100);
    timer->start();
}

void MxOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glEnable(GL_DEPTH_TEST);

    program = new QOpenGLShaderProgram(this);
    const char* vsrc = R"(
        in vec4 pos;
        in vec4 itextCoor;
        out vec4 otextCoor;
        uniform mat4 trans;
        void main() {
            gl_Position = trans * pos;
            otextCoor = itextCoor;
        })";
    program->addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc);
    const char* fsrc = R"(
        in vec4 otextCoor;
        void main() {
            gl_FragColor = otextCoor;
        })";
    program->addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc);

    program->link();
    program->bind();
}

void MxOpenGLWidget::paintGL()
{
    GLfloat vertices[] =
    {
        -0.8f, -0.4f, 0.3f,
        0.8f, -0.4f, 0.3f,
        0.0f, 0.8f, 0.0f,
        0.0f, -0.4f, -0.5f,
        -0.8f, -0.4f, 0.3f,
        0.8f, -0.4f, 0.3f,
    };
    GLfloat colors[] =
    {
        0.0f, 0.0f, 1.0f,
        0.0f, 1.0f, 0.0f,
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 1.0f,
        1.0f, 0.0f, 1.0f,
        1.0f, 1.0f, 0.0f,
    };

    QMatrix4x4 matrix;
    matrix.perspective(60.0f, 1.0f, 1.0f, 100.0f);
    matrix.translate(0, 0, -2);
    matrix.rotate(iter * 1.0f, 0, 1, 0);
    program->setUniformValue("trans", matrix);
    program->enableAttributeArray("trans");
    iter++;

    program->setAttributeArray("pos", vertices, 3);
    program->enableAttributeArray("pos");
    program->setAttributeArray("itextCoor", colors, 3);
    program->enableAttributeArray("itextCoor");
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
}

void MxOpenGLWidget::resizeGL(int w, int h)
{
}

程序运行效果如下图:

 

标签:0.8,1.0,Qt,例程,0.0,void,int,program,3D
From: https://www.cnblogs.com/mengxiangdu/p/17672585.html

相关文章

  • 『PyQt5-基础篇』| 03 基于PyQt5的第一个应用程序简单示例
    (03基于PyQt5的第一个应用程序简单示例)1导入必须的类需要两个类Application,QWidget;这两个类继承于QtWidgets;Application是应用程序类,QWidget是窗口类;sys模块是应用程序或窗口的参数会用到。importsysfromPyQt5.QtWidgetsimportQApplication,QWidget2创建Appli......
  • 如何使用javascript制作一个网页端3D贪吃蛇游戏(附源码)
    3D网页版贪吃蛇游戏!下面来具体讲一下如何实现。该游戏使用Hightopo的SDK制作,总共100多行代码,没有WebGL基础的同学们也可很快掌握。场景初始化首先,我们对页面进行初始化,包括初始化3D场景,设置地面网格,以及开启事件监听等。主要代码及注释如下:w=40;//网格间距m=20;//......
  • Unity3D下如何采集camera场景数据并推送RTMP服务?
    Unity3D使用场景Unity3D是非常流行的游戏开发引擎,可以创建各种类型的3D和2D游戏或其他互动应用程序。常见使用场景如下:游戏开发:Unity3D是一个广泛用于游戏开发的环境,适用于创建各种类型的游戏,包括动作游戏、角色扮演游戏、策略游戏、冒险游戏等。虚拟现实:Unity3D也常用于虚拟现实(VR......
  • 【Python进阶-PyQt5】00PyQt5简介
    0.图形用户界面-开发选择在Python基础的教程中,我们程序的用户交互界面都是运行窗口。这个运行窗口对于我们编程者来说直观明了,但是对于一些相对复杂的程序,用户使用上就会变得十分麻烦。所以,我们要通过设计用户交互界面来解决这种问题。程序的图形用户交互界面,英文称之为GUI(Grap......
  • Virtualbox中FreeBSD安装lxqt桌面后鼠标无响应
    1程序版本及问题Virtualbox7.0FreeBSD13.1xorg7.7_3lxqt1.3.0virtualbox-ose-additions6.1.46问题:通过startx启动lxqt桌面后鼠标无响应。2问题解决步骤打开/etc/X11/xorg.conf文件1定位到ServerLayout新增一行Option"AutoAddDevices""false"如下:Section"S......
  • MQTT协议
    1.MQTT协议介绍官网:http://mqtt.p2hp.com/MQTThttps://blog.csdn.net/weixin_36173034/article/details/1125110142.MQTT协议原理3.MQTT协议数据包结构Byte1:低4位MQTT消息质量QoS取决于发布者发布消息的Qos与订阅者订阅消息的Qos,取他们两者Qos最小的,即”木桶原理......
  • CSS基础-3D变形
    今天介绍两种3D变形的形式:3D旋转、空间位移。3D旋转在上一节2D变形中,我们用到了transform 属性。那么在3D旋转中同样还是这个属性(怎么老是它,手动狗头)。用rotateX()函数来给 transform 属性赋值,即可实现元素标签绕X(横)轴3D旋转。语法//绕横轴(盒子X轴中心线旋转3......
  • CF1833D Flipper 题解
    赛场上思路出来了但是代码没调出来。首先考虑右端点,很明显,要让操作后的序列字典序尽量地大,那么就要使操作后的序列第一个数尽量地大,考虑\(n\)或\(n-1\),如果\(n\)在原序列的第一个位置,那么此时无论怎么调整都无法使得它在新序列的第一个位置,此时就要考虑让\(n-1\)在新序列......
  • Learning Auxiliary Monocular Contexts Helps Monocular 3D Object Detection (2)
    Featurebackbone采用DLA,输入维度为3×H×W的RGB图,得到维度D×h×w的特征图F,然后将特征图送入几个轻量级regressionheads,2Dboudingboxes的中心特征图用下面的模块得到:其中AN是AttentiveNormalization.用公式表示:类似的,2D和3Dboudingboxes的中心之间的offset用公......
  • PyQt/PySide's qwindows.dll qwindowsvistastyle.dll is corrupted by UPX
    Windows1064-bitsPython3.8.1064-bitsPySide25.15.2PyInstaller4.3UPX4.1.0itraises:"ThisapplicationfailedtostartbecausenoQtplatformplugincouldbeinitialize"Solutioninspecfiles,addupx_exclude=['qwindows.dll'......