• QT中Shader类与多VAO、VBO的使用


    1. QOpenGLShaderProgram

    在不使用QOpenGLShaderProgram类时,OpenGL加载一个shader大概需要以下步骤:

    1. 创建着色器glCreateShader
    2. 绑定着色器glShaderSource
    3. 编译着色器glCompileShader
    4. 创建shader程序glCreateProgram
    5. 将着色器添加到shader程序glAttachShader
    6. 连接shader程序
    7. 使用shader程序glUseProgram
    8. 使用完后进行解绑

    示例如下:

    // 创建顶点着色器
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    // 绑定着色器
    glShaderSource(vertexShader,1,&vertexShaderSource,NULL);
    // 编译顶点着色器
    glCompileShader(vertexShader);
    
    // 创建片段着色器
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
    // 编译片段着色器
    glCompileShader(fragmentShader);
    
    // 链接 shaders
    m_shaderProgram = glCreateProgram();
    glAttachShader(m_shaderProgram,vertexShader);
    glAttachShader(m_shaderProgram,fragmentShader);
    glLinkProgram(m_shaderProgram);
    
    // 使用shader program
    glUseProgram(m_shaderProgram);
    
    // 使用完后进行解绑
    glUseProgram(0);
    
    

    使用QOpenGLShaderProgram后代码会相对简便非常多,步骤如下:

    1. QOpenGLShaderProgram设置shader源码
    2. 进行链接
    3. 进行绑定使用
    4. 使用完后进行解绑

    示例如下:

    // 添加顶点 shader
    m_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vertex_shader.vert");
    // 添加片段 shader
    m_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fragment_shader.frag");
    // 链接
    m_shaderProgram.link();
    // 绑定,只有在绑定完后才可以对这个shader的变量进行设置
    m_shaderProgram.bind();
    // 使用完后进行解绑
    m_shaderProgram.release();
    

    2. 多VAO、VBO使用

    VAOVBO在创建上与单VAOVBO的区别是通过数组形式创建,示例如下:

    // 创建VAO
    glGenVertexArrays(2, m_VAO);
    // 创建VBO
    glGenBuffers(2, m_VBO);
    
    // 解除VBO
    glDeleteBuffers(2,m_VBO);
    // 解除VAO
    glDeleteVertexArrays(2,m_VAO);
    

    2.1 用多VAO、VBO绘制两个不同的三角形

    1. VAOVBO的数据关联绑定,代码如下:
      // 绑定VAO和VBO对象
      glBindVertexArray(m_VAO[0]);
      glBindBuffer(GL_ARRAY_BUFFER, m_VBO[0]);
      
      // 为缓冲对象创建一个新的数据存储
      glBufferData(GL_ARRAY_BUFFER, sizeof(firstTriangle), firstTriangle, GL_STATIC_DRAW);
      
      /*
      * 定义一个通用顶点属性数据数组:告诉显卡如何解析缓冲里的属性值
      *   index:指定要修改的通用顶点属性的索引值
      *   size:指定通用顶点属性的分量,必须为1、2、3或4,初始值为4
      *   type:指定数组中每个元素得到类型,初始值为GL_FLOAT
      *   normalized:指定在访问定点数据值时是否应将其归一化 (GL_TRUE) 或直接转换为定点值 (GL_FALSE)
      *   stride:指定数组中每个通用顶点属性的步长
      *   pointer:指定通用顶点属性的属性的起始位置
      */
      glVertexAttribPointer(0, 3, GL_FLOAT, GL_TRUE, 3 * sizeof(GLfloat), (void*)0);
      
      // 开启VAO管理的第一个属性值  VAO[0] 的第一个属性
      glEnableVertexAttribArray(0);
      
      // 解绑
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      glBindVertexArray(0);
      
      // 绑定VAO和VBO对象
      glBindVertexArray(m_VAO[1]);
      glBindBuffer(GL_ARRAY_BUFFER, m_VBO[1]);
      
      // 为缓冲对象创建一个新的数据存储
      glBufferData(GL_ARRAY_BUFFER, sizeof(secondTriangle), secondTriangle, GL_STATIC_DRAW);
      
      /*
      * 定义一个通用顶点属性数据数组:告诉显卡如何解析缓冲里的属性值
      */
      glVertexAttribPointer(0, 3, GL_FLOAT, GL_TRUE, 3 * sizeof(GLfloat), (void*)0);
      
      // 开启VAO管理的第一个属性值  VAO[1] 的第一个属性
      glEnableVertexAttribArray(0);
      // 解绑
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      glBindVertexArray(0);
      
      
    2. 绘制三角形
      绘制代码里主要是,不同VAO的切换,如下:
      glBindVertexArray(m_VAO[0]);
      glDrawArrays(GL_TRIANGLES, 0, 3);
      glBindVertexArray(0);
      
      glBindVertexArray(m_VAO[1]);
      glDrawArrays(GL_TRIANGLES, 0, 3);
      glBindVertexArray(0);
      

    3. 效果展示

    在这里插入图片描述

    4. 源码

    源码链接

  • 相关阅读:
    Python常考面试题汇总
    【C++】如何释放vector的内存空间及std::vector::shrink_to_fit用法简介
    Lec14 File systems 笔记
    python 实现两个文本文件内容去重
    vue-admin-better前端页面-菜单-权限配置
    【小程序】常见系统API | 页面分享 | 位置信息 | 本地存储
    Python数据分析案例04——超高维数据的降维(随机森林)、特征工程
    C++ Qt开发:Tab与Tree组件实现分页菜单
    grafana api创建dashboard 记录
    数字孪生在能源、电力系统、电厂行业的应用实例
  • 原文地址:https://blog.csdn.net/weixin_41111116/article/details/127039505