zoukankan      html  css  js  c++  java
  • 2.通过QOpenGLWidget绘制三角形

    1.QOpenGLWidget的早先版本
    QGLWidget是遗留Qt OpenGL模块的一部分,和其他QGL类一样,应该在新的应用程序中避免使用。相反,从Qt 5.4开始,最好使用QOpenGLWidget和QOpenGL类。
    如果开发XP平台,由于兼容性问题,Qt5.4(不含)之后的QtOpenglWidget 则不兼容,建议还是用QGLWidget.
     
    2.QOpenGLWidget类是用于呈现OpenGL图形的部件
            QOpenGLWidget提供显示集成到Qt应用程序中的OpenGL图形的功能。使用起来非常简单:让类继承它,并像其他QWidget一样使用子类,额外可以选择使用QPainer和标准的OpenGL渲染命令。
            QOpenGLWidget提供了三个方便的虚拟函数,子类中重新实现这些函数来执行OpenGL绘制任务:
    • paintGL():渲染OpenGL场景。该函数里面主要绘制部件,比如在全屏视频上面显示滑动条
    • resizeGL ():当窗口尺寸发生变化时被调用,然后会调用paintGL()函数重新绘制一次(并且第一次显示时也会调用resizeGL() )。
    • initializeGL():用于初始化,设置OpenGL要呈现的画面,只在程序开始时运行一次,之后不会再运行。
    其中在initializeGL()中初始化具体如下所示:
    然后在paintGL()中,每次当我们要绘制不同的物体时,便调用bind()来绑定对象、绘制完后,解绑对象,如果还要绘制下个物体,那么就取出对应的VAO,绑定它,绘制完物体后,再解绑。
     
    3.三角形示例
    4.头文件代码
    #ifndef MYGLWIDGET_H
    #define MYGLWIDGET_H
     
    #include <QMainWindow>
    #include <QObject>
    #include <QWidget>
    #include <QOpenGLWidget>
    #include <QOpenGLFunctions>
    #include <QOpenGLShaderProgram>
    #include <QOpenGLBuffer>
    #include <QOpenGLVertexArrayObject>
    class myGlWidget : public QOpenGLWidget , protected QOpenGLFunctions
    {
    Q_OBJECT
    public:
     
    myGlWidget(QWidget *parent = nullptr);
    protected:
     
    void paintGL() ;
    void initializeGL() ;
    void resizeEvent(QResizeEvent *e) ;
     
     
    private:
    QOpenGLShaderProgram *program;
     
    QOpenGLVertexArrayObject vao;
    QOpenGLBuffer vbo;
     
    };
     
    #endif // MYGLWIDGET_H

    5.源文件代码

    #include "myglwidget.h"
    #include <QtDebug>
    
    
    //GLSL3.0版本后,废弃了attribute关键字(以及varying关键字),属性变量统一用in/out作为前置关键字
    #define GL_VERSION  "#version 330 core
    "
    
    #define GLCHA(x)  #@x           //加单引号,将x变为字符
    #define GLSTR(x)  #x            //加双引号,将x变为字符串
    #define GET_GLSTR(x) GL_VERSION#x
    
    
    const char *vsrc = GET_GLSTR(
        layout (location = 0) in vec3 aPos;
        void main(void)
        {
          gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
        }
    );
    
    const char *fsrc =GET_GLSTR(
                out vec4 FragColor;
                void main(void)
                {
                  FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);
                }
    );
    
    //fsrc 等价于 -->   const char *fsrc ="#version 330 core
    "
    //                      "out vec4 FragColor;
    "
    //                      "void main()
    "
    //                      "{
    "
    //                      "   FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);
    "
    //                      "}
    ";
    
    myGlWidget::myGlWidget(QWidget *parent):QOpenGLWidget(parent)
    {
    
    }
    
    
    void myGlWidget::paintGL()
    {
       // 绘制
      // glViewport(0, 0, width(), height());
    
       glClear(GL_COLOR_BUFFER_BIT);
    
       // 渲染Shader
       program->bind(); //绑定激活Program对象
       vao.bind();      //绑定激活vao
       glDrawArrays(GL_TRIANGLES, 0, 3);    //绘制3个定点,样式为三角形
       vao.release();       //解绑
       program->release();  //解绑
    
    }
    void myGlWidget::initializeGL()
    {
    
       // 为当前环境初始化OpenGL函数
       initializeOpenGLFunctions();
    
       glClearColor(1.0f, 1.0f, 1.0f, 1.0f);    //设置背景色为白色
    
       //1.创建顶点着色器
       QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
       vshader->compileSourceCode(vsrc);
    
       //2.创建片元着色器 rgba(1.0f, 1.0f, 0.0f, 1.0f)表示黄色,而alpha值为1.0,表示完全不透明
       QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
       fshader->compileSourceCode(fsrc);
    
       //3.创建着色器程序
       program = new QOpenGLShaderProgram;
       program->addShader(vshader);
       program->addShader(fshader);
       program->link();
       program->bind();//激活Program对象
    
    
       //4.初始化VBO,将顶点数据存储到buffer中,等待VAO激活后才能释放
       float vertices[] = {
       -0.5f, -0.5f, 0.0f,
       0.5f, -0.5f, 0.0f,
       0.0f, 0.5f, 0.0f
       };
    
       vbo.create();
       vbo.bind();              //绑定到当前的OpenGL上下文,
       vbo.allocate(vertices, 9*sizeof(GLfloat));
       vbo.setUsagePattern(QOpenGLBuffer::StreamDraw);  //设置为一次修改,多次使用
    
    
       //5.初始化VAO,设置顶点数据状态(顶点,法线,纹理坐标等)
       vao.create();
       vao.bind();
    
       GLint aPos = program->attributeLocation("aPos");        //获取aPos位置
       if(aPos==-1)  //未找到
       {
           return;
       }
       program->setAttributeBuffer(aPos, GL_FLOAT, 0,  3, 0);   //设置顶点属性
       program->enableAttributeArray(aPos); //使能顶点属性
    
    
       //6.解绑所有对象
       vao.release();
       vbo.release();
       program->release();
    
    
    }
    void myGlWidget::resizeEvent(QResizeEvent *e)
    {
    
    
    }

     下章学习:

    3.QOpenGLWidget-通过着色器来渲染渐变三角形

     

  • 相关阅读:
    css-Less
    linux脚本启动应用
    Idea安装svn插件
    一、JSP九大内置对象 二、JAVAEE三层架构和MVC设计模式 三、Ajax
    一、HttpServletRequest接口 二、HttpServletReponse接口 三、POST和GET请求方式及其乱码处理 四、ServletContext对象和ServletConfig对象
    一、 JSP概述 二、JSP的语法结构 三、JSP内置对象
    一、动态网络编程的概念 二、Tomcat服务器搭建 三、Servlet组件介绍
    一、BOM 二、DOM
    一、JavaScript概述 二、JavaScript的语法 三、JavaScript的内置对象
    一、HTML概述 二、web相关的概念 三、HTML的常用标签
  • 原文地址:https://www.cnblogs.com/lifexy/p/13723939.html
Copyright © 2011-2022 走看看