zoukankan      html  css  js  c++  java
  • 矩阵转换

    原文:https://www.jianshu.com/p/62fb681df39c

    Qt中有对应的QMatrix4x4处理4维矩阵

    使用OpenGL函数版

    #include "widget.h"
    #include "ui_widget.h"
    #include <QTImer>
    #include <QDebug>
    
    static GLuint VBO, VAO, EBO, texture1, texture2;
    
    Widget::Widget(QWidget *parent) :
        QOpenGLWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
        m_timer = new QTimer(this);
        m_nTimeValue = 0;
        connect(m_timer,&QTimer::timeout,this,&slotTimer);
        m_timer->start(50);
    }
    
    void Widget::slotTimer()
    {
        m_nTimeValue += 5;
        update();
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::initializeGL()
    {
        this->initializeOpenGLFunctions();
    
        int success = m_program.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shader/textures.vert");
        if (!success) {
            qDebug() << "program addShaderFromSourceFile Failed." << m_program.log();
            return;
        }
        success = m_program.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shader/textures.frag");
        if (!success) {
            qDebug() << "program addShaderFromSourceFile Failed." << m_program.log();
            return;
        }
        success = m_program.link();
        if (!success) {
            qDebug() << "program link Failed." << m_program.log();
        }
    
        // VAO VBO VEO data
        float vertices[] = {
            // positions          // colors           // texture coords
             0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
             0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
            -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
            -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left
        };
        unsigned int indices[] = {  // note that we start from 0!
            0, 1, 3,  // first Triangle
            1, 2, 3   // second Triangle
        };
    
        glGenVertexArrays(1,&VAO);
        glGenBuffers(1,&VBO);
        glGenBuffers(1,&EBO);
    
         // bind the Vertex Array Object first, then bind and set vertex buffer(s),
        // and then configure vertex attributes(s).
    
        glBindVertexArray(VAO);
    
        glBindBuffer(GL_ARRAY_BUFFER,VBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
    
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);
    
        // position attribute
        glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,8*sizeof(float),(void*)0);
        glEnableVertexAttribArray(0);
        // color attribute
        glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,8*sizeof(float),(void*)(3*sizeof(float)));
        glEnableVertexAttribArray(1);
        // texture coords
        glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,8*sizeof(float),(void*)(6*sizeof(float)));
        glEnableVertexAttribArray(2);
    
        // texture1
        glGenTextures(1,&texture1);
        glBindTexture(GL_TEXTURE_2D,texture1);
    
        // set texture wrapping parameters
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
        // SET texture filting parameters
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        // load image,create texture,generate mipmaps
        QImage image1 = QImage(":/image/image/container.jpg").convertToFormat(QImage::Format_RGB888);
        if (!image1.isNull()){
            glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,image1.width(),image1.height(),0,GL_RGB,GL_UNSIGNED_BYTE,image1.bits());
            glGenerateMipmap(GL_TEXTURE_2D);
        }
    
        // texture2
        glGenTextures(1,&texture2);
        glBindTexture(GL_TEXTURE_2D,texture2);
    
        // set texture wrapping parameters
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
        // SET texture filting parameters
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        // load image,create texture,generate mipmaps
        QImage image2 = QImage(":/image/image/awesomeface.png").convertToFormat(QImage::Format_RGBA8888).mirrored(true, true);
        if (!image2.isNull()){
            // note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA
            glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,image2.width(),image2.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,image2.bits());
            glGenerateMipmap(GL_TEXTURE_2D);
        }
    
        // tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
        m_program.bind();   // don't forget to activate/use the shader before setting uniforms!
        glUniform1i(m_program.uniformLocation("texture1"),0);
        glUniform1i(m_program.uniformLocation("texture2"),1);
        m_program.release();
    }
    
    void Widget::resizeGL(int w, int h)
    {
        glViewport(0,0,w,h);
    }
    
    void Widget::paintGL()
    {
        glClearColor(0.2f,0.3f,0.3f,1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
    
        // bind textures on corresponding texture units
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D,texture1);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D,texture2);
    
    
        // create transformations
        QMatrix4x4 transform;
        transform.translate(QVector3D(0.5f, -0.5f, 0.0f));
        transform.rotate(m_nTimeValue, QVector3D(0.0f, 0.0f, 1.0f));
    
        // get matrix's uniform location and set matrix
        m_program.bind();
        int transformLoc = m_program.uniformLocation("transform");
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, transform.data());
    
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,NULL);
        m_program.release();
    }
    cpp
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QOpenGLWidget>
    #include <QOpenGLFunctions_3_3_Core>
    #include <QOpenGLShader>
    #include <QOpenGLShaderProgram>
    
    
    namespace Ui {
    class Widget;
    }
    
    class Widget : public QOpenGLWidget,protected QOpenGLFunctions_3_3_Core
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();
    
    protected:
        virtual void initializeGL();
        virtual void resizeGL(int w,int h);
        virtual void paintGL();
    public slots:
        void slotTimer();
    private:
        QOpenGLShaderProgram m_program;
        QTimer* m_timer;
        int m_nTimeValue;
    private:
        Ui::Widget *ui;
    };
    
    #endif // WIDGET_H
    hpp
    析构函数要记得释放
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
        glDeleteBuffers(1, &EBO);
    #version 330 core
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec3 aColor;
    layout (location = 2) in vec2 aTexCoord;
    
    out vec3 ourColor;
    out vec2 TexCoord;
    
    uniform mat4 transform;
    
    void main()
    {
        gl_Position = transform * vec4(aPos, 1.0f);
        ourColor = aColor;
        TexCoord = aTexCoord;
        //TexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y);
    }
    texture.vert
    #version 330 core
    out vec4 FragColor;
    
    in vec3 ourColor;
    in vec2 TexCoord;
    
    uniform sampler2D texture1;
    uniform sampler2D texture2;
    
    void main()
    {
        //FragColor = texture(texture1, TexCoord) * vec4(ourColor, 1.0);
        FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
    }
    fragment.frag

    使用Qt相关函数版

    尝试再次调用glDrawElements画出第二个箱子,使用变换将其摆放在不同的位置。让这个箱子被摆放在窗口的左上角,并且会不断的缩放(而不是旋转)

    #include "qtfunwidget.h"
    #include <QTimer>
    
    QtFunWidget::QtFunWidget(QWidget *parent)
        : QOpenGLWidget(parent)
        ,vbo(QOpenGLBuffer::VertexBuffer)
        ,ebo(QOpenGLBuffer::IndexBuffer)
    {
        m_timer = new QTimer(this);
        connect(m_timer,&QTimer::timeout,this,[=]{
            m_timeValue += 5;
            update();
        });
        m_timer->start(50);
    }
    
    QtFunWidget::~QtFunWidget()
    {
        /*Prepares for rendering OpenGL content for this widget by making
         * the corresponding context current and binding the framebuffer object in that context.
    
            It is not necessary to call this function in most cases,
            because it is called automatically before invoking paintGL().
        */
        makeCurrent();
        vbo.destroy();
        ebo.destroy();
    
        if(texture1)
            delete texture1;
        if(texture2)
            delete texture2;
    
        doneCurrent();
    }
    
    void QtFunWidget::initializeGL()
    {
        this->initializeOpenGLFunctions();
        int success = m_program.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shader/textures.vert");
        if (!success) {
            qDebug() << "program addShaderFromSourceFile Failed." << m_program.log();
            return;
        }
        success = m_program.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shader/textures.frag");
        if (!success) {
            qDebug() << "program addShaderFromSourceFile Failed." << m_program.log();
            return;
        }
        success = m_program.link();
        if (!success) {
            qDebug() << "program link Failed." << m_program.log();
        }
    
        // VAO VBO VEO data
        float vertices[] = {
            // positions          // colors           // texture coords
             0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
             0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
            -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
            -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left
        };
        unsigned int indices[] = {  // note that we start from 0!
            0, 1, 3,  // first Triangle
            1, 2, 3   // second Triangle
        };
    
        QOpenGLVertexArrayObject::Binder vaobind(&vao);
    
        vbo.create();
        vbo.bind();
        vbo.allocate(vertices,sizeof(vertices));
    
        ebo.create();
        ebo.bind();
        ebo.allocate(indices,sizeof(indices));
    
        // position attribute
        int attr = -1;
        attr = m_program.attributeLocation("aPos");
        m_program.setAttributeBuffer(attr,GL_FLOAT,0,3,8*sizeof(GL_FLOAT));
        m_program.enableAttributeArray(attr);
        // color attribute
        attr = m_program.attributeLocation("aColor");
        m_program.setAttributeBuffer(attr,GL_FLOAT,3*sizeof(GL_FLOAT),3,8*sizeof(GL_FLOAT));
        m_program.enableAttributeArray(attr);
    
       // texture coord attribute
        attr = m_program.attributeLocation("aTexCoord");
        m_program.setAttributeBuffer(attr,GL_FLOAT,6*sizeof(GL_FLOAT),2,8*sizeof(GL_FLOAT));
        m_program.enableAttributeArray(attr);
    
        // texture1
        //直接生成绑定一个2d纹理, 并生成多级纹理MipMaps
        texture1 = new QOpenGLTexture(QImage(":/image/container.jpg"),QOpenGLTexture::GenerateMipMaps);
        if(!texture1->isCreated()){
            qDebug() << "failed to load texture.";
        }
        texture1->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);// 等于glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        texture1->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);//    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        // set texture filtering parameters
        texture1->setMinificationFilter(QOpenGLTexture::Linear);   //等价于glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        texture1->setMagnificationFilter(QOpenGLTexture::Linear);
    
        // texture2
        //直接生成绑定一个2d纹理, 并生成多级纹理MipMaps
        texture2 = new QOpenGLTexture(QImage(":/image/awesomeface.png").mirrored(true,true),QOpenGLTexture::GenerateMipMaps);
        if(!texture2->isCreated()){
            qDebug() << "failed to load texture.";
        }
        texture2->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);// 等于glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        texture2->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);//    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        // set texture filtering parameters
        texture2->setMinificationFilter(QOpenGLTexture::Linear);   //等价于glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        texture2->setMagnificationFilter(QOpenGLTexture::Linear);
    
        m_program.bind();
        m_program.setUniformValue("texture1",0);
        m_program.setUniformValue("texture2",1);
    
        vbo.release();
    //    remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
    //    ebo.release();
    }
    
    void QtFunWidget::resizeGL(int w, int h)
    {
        glViewport(0,0,w,h);
    }
    
    void QtFunWidget::paintGL()
    {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
    
        // bind textures on corresponding texture units
        glActiveTexture(GL_TEXTURE0);
        texture1->bind();
        glActiveTexture(GL_TEXTURE1);
        texture2->bind();
    
        // create transformations
        QMatrix4x4 transform;
        transform.translate(QVector3D(0.5f, -0.5f, 0.0f));
        transform.rotate(m_timeValue, QVector3D(0.0f, 0.0f, 1.0f));
    
        m_program.bind();
        m_program.setUniformValue("transform", transform);
    
        {// render container
            QOpenGLVertexArrayObject::Binder vaoBind(&vao);
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
        }
    
        // create transformations
        QMatrix4x4 transform2;
        transform2.translate(QVector3D(-0.5f, 0.5f, 0.0f));
        float scaleAmount = sin(m_timeValue);
        transform2.scale(QVector3D(scaleAmount, scaleAmount, scaleAmount));
    
        //m_program.bind();
        m_program.setUniformValue("transform", transform2);
    
        {// render container
            QOpenGLVertexArrayObject::Binder vaoBind(&vao);
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
        }
    
        texture1->release();
        texture2->release();
        m_program.release();
    }
    两个箱子
    #include "qtfunwidget.h"
    #include <QTimer>
    
    QtFunWidget::QtFunWidget(QWidget *parent)
        : QOpenGLWidget(parent)
        ,vbo(QOpenGLBuffer::VertexBuffer)
        ,ebo(QOpenGLBuffer::IndexBuffer)
    {
        m_timer = new QTimer(this);
        connect(m_timer,&QTimer::timeout,this,[=]{
            m_timeValue += 5;
            update();
        });
        m_timer->start(50);
    }
    
    QtFunWidget::~QtFunWidget()
    {
        /*Prepares for rendering OpenGL content for this widget by making
         * the corresponding context current and binding the framebuffer object in that context.
    
            It is not necessary to call this function in most cases,
            because it is called automatically before invoking paintGL().
        */
        makeCurrent();
        vbo.destroy();
        ebo.destroy();
    
        if(texture1)
            delete texture1;
        if(texture2)
            delete texture2;
    
        doneCurrent();
    }
    
    void QtFunWidget::initializeGL()
    {
        this->initializeOpenGLFunctions();
        int success = m_program.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shader/textures.vert");
        if (!success) {
            qDebug() << "program addShaderFromSourceFile Failed." << m_program.log();
            return;
        }
        success = m_program.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shader/textures.frag");
        if (!success) {
            qDebug() << "program addShaderFromSourceFile Failed." << m_program.log();
            return;
        }
        success = m_program.link();
        if (!success) {
            qDebug() << "program link Failed." << m_program.log();
        }
    
        // VAO VBO VEO data
        float vertices[] = {
            // positions          // colors           // texture coords
             0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
             0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
            -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
            -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left
        };
        unsigned int indices[] = {  // note that we start from 0!
            0, 1, 3,  // first Triangle
            1, 2, 3   // second Triangle
        };
    
        QOpenGLVertexArrayObject::Binder vaobind(&vao);
    
        vbo.create();
        vbo.bind();
        vbo.allocate(vertices,sizeof(vertices));
    
        ebo.create();
        ebo.bind();
        ebo.allocate(indices,sizeof(indices));
    
        // position attribute
        int attr = -1;
        attr = m_program.attributeLocation("aPos");
        m_program.setAttributeBuffer(attr,GL_FLOAT,0,3,8*sizeof(GL_FLOAT));
        m_program.enableAttributeArray(attr);
        // color attribute
        attr = m_program.attributeLocation("aColor");
        m_program.setAttributeBuffer(attr,GL_FLOAT,3*sizeof(GL_FLOAT),3,8*sizeof(GL_FLOAT));
        m_program.enableAttributeArray(attr);
    
       // texture coord attribute
        attr = m_program.attributeLocation("aTexCoord");
        m_program.setAttributeBuffer(attr,GL_FLOAT,6*sizeof(GL_FLOAT),2,8*sizeof(GL_FLOAT));
        m_program.enableAttributeArray(attr);
    
        // texture1
        //直接生成绑定一个2d纹理, 并生成多级纹理MipMaps
        texture1 = new QOpenGLTexture(QImage(":/image/container.jpg"),QOpenGLTexture::GenerateMipMaps);
        if(!texture1->isCreated()){
            qDebug() << "failed to load texture.";
        }
        texture1->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);// 等于glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        texture1->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);//    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        // set texture filtering parameters
        texture1->setMinificationFilter(QOpenGLTexture::Linear);   //等价于glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        texture1->setMagnificationFilter(QOpenGLTexture::Linear);
    
        // texture2
        //直接生成绑定一个2d纹理, 并生成多级纹理MipMaps
        texture2 = new QOpenGLTexture(QImage(":/image/awesomeface.png").mirrored(true,true),QOpenGLTexture::GenerateMipMaps);
        if(!texture2->isCreated()){
            qDebug() << "failed to load texture.";
        }
        texture2->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);// 等于glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        texture2->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);//    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        // set texture filtering parameters
        texture2->setMinificationFilter(QOpenGLTexture::Linear);   //等价于glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        texture2->setMagnificationFilter(QOpenGLTexture::Linear);
    
        m_program.bind();
        m_program.setUniformValue("texture1",0);
        m_program.setUniformValue("texture2",1);
    
        vbo.release();
    //    remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
    //    ebo.release();
    }
    
    void QtFunWidget::resizeGL(int w, int h)
    {
        glViewport(0,0,w,h);
    }
    
    void QtFunWidget::paintGL()
    {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
    
        // bind textures on corresponding texture units
        glActiveTexture(GL_TEXTURE0);
        texture1->bind();
        glActiveTexture(GL_TEXTURE1);
        texture2->bind();
    
        // create transformations
        QMatrix4x4 transform;
        transform.translate(QVector3D(0.5f, -0.5f, 0.0f));
        transform.rotate(m_timeValue, QVector3D(0.0f, 0.0f, 1.0f));
    
        m_program.bind();
        m_program.setUniformValue("transform", transform);
    
        {// render container
            QOpenGLVertexArrayObject::Binder vaoBind(&vao);
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
        }
    
        texture1->release();
        texture2->release();
        m_program.release();
    }
    .cpp
    #ifndef QTFUNWIDGET_H
    #define QTFUNWIDGET_H
    
    #include <QWidget>
    #include <QOpenGLWidget>
    #include <QOpenGLShader>
    #include <QOpenGLShaderProgram>
    #include <QOpenGLFunctions>
    #include <QOpenGLVertexArrayObject>
    #include <QOpenGLBuffer>
    #include <QOpenGLTexture>
    
    class QtFunWidget : public QOpenGLWidget,protected QOpenGLFunctions
    {
        Q_OBJECT
    
    public:
        QtFunWidget(QWidget *parent = 0);
        ~QtFunWidget() Q_DECL_OVERRIDE;
    protected:
        virtual void initializeGL() Q_DECL_OVERRIDE;
        virtual void resizeGL(int w,int h) Q_DECL_OVERRIDE;
        virtual void paintGL() Q_DECL_OVERRIDE;
    private:
        QOpenGLShaderProgram m_program;
        QOpenGLBuffer vbo,ebo;
        QOpenGLVertexArrayObject vao;
        QOpenGLTexture *texture1{nullptr};
        QOpenGLTexture *texture2{nullptr};
    
        QTimer *m_timer{nullptr};
        int m_timeValue{0};
    };
    
    #endif // QTFUNWIDGET_H
    .hpp
  • 相关阅读:
    postman的使用方法详解!最全面的教程
    免费使用的加速器
    Windows添加启动项的两种方法
    Python版本微信跳一跳,软件配置
    Inno Setup教程
    Go开发环境安装配置
    Linux下安装Phantomjs
    Python的url解析库--urlparse
    Python处理HTML转义字符
    Python使用base64编码的问题
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/12073460.html
Copyright © 2011-2022 走看看