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. 源码

源码链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值