zoukankan      html  css  js  c++  java
  • 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;
    }


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

  • 相关阅读:
    5.2 二叉树的创建和遍历
    5 树
    Word2013发布博客到博客园的详细方法
    synergy--共享你的键鼠
    二十三 Python分布式爬虫打造搜索引擎Scrapy精讲—craw母版l创建自动爬虫文件—以及 scrapy item loader机制
    二十二 Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy模拟登陆和知乎倒立文字验证码识别
    二十一 Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫数据保存
    二十 Python分布式爬虫打造搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器
    十九 Python分布式爬虫打造搜索引擎Scrapy精讲—css选择器
    十八 Python分布式爬虫打造搜索引擎Scrapy精讲—Scrapy启动文件的配置—xpath表达式
  • 原文地址:https://www.cnblogs.com/gispathfinder/p/10903273.html
Copyright © 2011-2022 走看看