• QT+OpenGL(01)--实现三角形渲染


    1.openglwidget.ui


    <ui version="4.0">
     <author/>
     <comment/>
     <exportmacro/>
     <class>OpenGLWidget</class>
     <widget class="QWidget" name="OpenGLWidget">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>400</width>
        <height>300</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>Form</string>
      </property>
     </widget>
     <pixmapfunction/>
     <connections/>
    </ui>


    2. openglwidget.h

    #ifndef OPENGLWIDGET_H
    #define OPENGLWIDGET_H
    
    #include <QWidget>
    #include <QOpenGLWidget>
    #include <QOpenGLFunctions>
    #include <GL/gl.h>
    #include <qopengl.h>
    #include <qopenglfunctions.h>
    #include <qopenglshaderprogram.h>
    
    namespace Ui {
    class OpenGLWidget;
    }
    
    class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
    {
        Q_OBJECT
    
    
    public:
        QOpenGLShaderProgram* program;
        GLuint programId;
        GLuint verVbo;
        GLuint indexVbo;
        GLuint colorVbo;
        GLuint  matrixLocation;
        GLuint vertexLocation;
        GLuint clorLocation;
        QMatrix4x4  projection;
        GLsizei vVerticesLen;
        GLsizei triIndexLen;
        GLsizei colorsLen ;
    
        GLuint triIndexs[3] = {0, 1, 2};
        GLfloat vertex[6] = {
            -0.5f, 0.0f,
            0.5f, 0.0f,
            0.0f, 0.5f,
        };
        GLfloat colors[12] = {1.0f, 0.0f, 0.0f, 1.0f,
                            0.0f, 1.0f, 0.0f, 1.0f,
                            0.0f, 0.0f, 1.0f, 1.0f,
                           };
    
        explicit OpenGLWidget(QWidget *parent = nullptr);
        ~OpenGLWidget();
    
    
    //    //三角形顶点坐标
    //    GLfloat* vertex;
    
    //    //三角形顶点索引
    //    GLuint* triIndexs;
    
    //    //三角形顶点颜色
    //    GLfloat* colors;
    
    
    private:
        Ui::OpenGLWidget *ui;
    protected:
        void initializeGL();
        void paintGL();
        void resizeGL(int w, int h);
        void initVbo();
    };
    
    #endif // OPENGLWIDGET_H


    3. openglwidget.cpp

    #include "openglwidget.h"
    #include "ui_openglwidget.h"
    #include <GL/gl.h>
    #include <qopengl.h>
    #include <qopenglfunctions.h>
    #include <qopenglshaderprogram.h>
    
    
    
    OpenGLWidget::OpenGLWidget(QWidget *parent) :
        QOpenGLWidget(parent),
        ui(new Ui::OpenGLWidget)
    {
        ui->setupUi(this);
    }
    
    
    
    OpenGLWidget::~OpenGLWidget()
    {
        delete ui;
    }
    
    void OpenGLWidget::initializeGL()
    {
        //调用内容初始化函数
        initializeOpenGLFunctions();
    
        program = new QOpenGLShaderProgram(this);
    
        if(!program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vertexshader.vect")){
            printf("no found vertexshader.vert");
            return;
        }
        if(!program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/fragmentshader.frag")){
            printf("no found fragmentshader.frag");
            return;
        }
        if(!program->link()){
            printf("no link");
            return;
        }
        if(!program->bind()){
            printf("no bind");
            return;
        }
    
        // 获取shaderprogram的id号,然后可以通过id号获取一些属性...
        programId = program->programId();
        printf("programId: %d", programId);
        // 从shaderprogram里面获取变量标识
        matrixLocation = glGetUniformLocation(programId, "matrix");
        vertexLocation = glGetAttribLocation(programId, "vPosition");
        clorLocation = glGetAttribLocation(programId, "vColor");
    
        initVbo();
    }
    void OpenGLWidget::initVbo(){
    
        // 计算获得数组长度
        vVerticesLen = sizeof(vertex)/sizeof(GLfloat);
        triIndexLen = sizeof(triIndexs)/sizeof(GLuint);
        colorsLen = sizeof(colors)/sizeof(GLfloat);
    
        // 初始化顶点buffer并装载数据到显存
    
    
        glGenBuffers(1, &verVbo);
        glBindBuffer(GL_ARRAY_BUFFER, verVbo);
        glBufferData(GL_ARRAY_BUFFER, vVerticesLen * sizeof(GLfloat), vertex, GL_STATIC_DRAW);
    
        // 初始化索引buffer并装载数据到显存
        glGenBuffers(1, &indexVbo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, triIndexLen * sizeof(GLuint), triIndexs, GL_STATIC_DRAW);
    
        // 初始化颜色buffer并装载数据到显存
        glGenBuffers(1, &colorVbo);
        glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
        glBufferData(GL_ARRAY_BUFFER, colorsLen * sizeof(GLfloat), colors, GL_STATIC_DRAW);
    }
    
    
    void OpenGLWidget::resizeGL(int w, int h)
    {
        //当窗口大小改变时,调整界面坐标显示高度和宽度
        glViewport(0, 0, w, h);
    
        // 模型矩阵重置
        projection.setToIdentity();
        // 透视投影
        qreal aspect = qreal(w) / qreal(h ? h : 1);
        projection.perspective(60.0f, aspect, 1.0f, 100.0f);
        // 增加了模型矩阵,需要做一定偏移量,保证物体刚开始渲染出来时可以被看到!
        projection.translate(0.0f, 0.0f, -2.0f);
    
    }
    
    void OpenGLWidget::paintGL()
    {
        //清除之前图形并将背景设置为黑色(设置为黑色纯粹个人爱好!)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    
        // shader传入模型视图矩阵 projection可以理解为建立了一个坐标系空间,可以再这个空间内设置图形
        glUniformMatrix4fv(matrixLocation, 1, GL_FALSE, projection.data());
    
        // shader绑定并启用颜色数组buffer
        glBindBuffer(GL_ARRAY_BUFFER,colorVbo);
        glVertexAttribPointer(clorLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(clorLocation);
        // 颜色值rgba,所以每四个float值作为一个颜色值,如果只是希望rgb,取三个值作为颜色值即可!
    
    
        // shader绑定并启用顶点数组buffer
        glBindBuffer(GL_ARRAY_BUFFER, verVbo);
        glVertexAttribPointer( vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(vertexLocation);
    
        // shader绑定并顶点索引数组buffer - 索引无需启用
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexVbo);
        glDrawElements(GL_TRIANGLES, triIndexLen, GL_UNSIGNED_INT, 0);
    
        // 解绑buffer、关闭启用顶点、颜色数组
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glDisableVertexAttribArray(vertexLocation);
        glDisableVertexAttribArray(clorLocation);
    
    }


    4. vertexshader.vect

    //vertexshader.vert
    uniform mat4 matrix;
    in vec4 vPosition;
    in vec4 vColor;
    out vec4 fColor;
    
    void main(void)
    {
        fColor = vColor;
        gl_Position = matrix * vPosition;
    }


    5. fragmentshader.frag

    //fragmentshader.frag
    in vec4 fColor;
    
    void main(void)
    {
        gl_FragColor = fColor;
    }


    ------------------------------------------------------------------------------------------------------

  • 相关阅读:
    Data truncation: Out of range value for column 'quanity' at row 问题解决方案
    nginx 提示the "ssl" directive is deprecated, use the "listen ... ssl" directive instead
    集合源码分析[3]-ArrayList 源码分析
    集合源码分析[2]-AbstractList 源码分析
    IDEA升级版本后界面出现变小,字体变细的问题解决
    集合源码分析[1]-Collection 源码分析
    kubernetes学习第一篇-k8s安装以及HelloWorld
    shiro多Realm第一次调用不生效问题
    设计模式学习(二)-简单工厂模式
    根据具体的地址解析出对应的地区码
  • 原文地址:https://www.cnblogs.com/gispathfinder/p/10903273.html
Copyright © 2020-2023  润新知