在不使用QOpenGLShaderProgram
类时,OpenGL
加载一个shader
大概需要以下步骤:
glCreateShader
glShaderSource
glCompileShader
shader
程序glCreateProgram
shader
程序glAttachShader
shader
程序shader
程序glUseProgram
示例如下:
// 创建顶点着色器
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
后代码会相对简便非常多,步骤如下:
QOpenGLShaderProgram
设置shader
源码示例如下:
// 添加顶点 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();
多VAO
、VBO
在创建上与单VAO
、VBO
的区别是通过数组形式创建,示例如下:
// 创建VAO
glGenVertexArrays(2, m_VAO);
// 创建VBO
glGenBuffers(2, m_VBO);
// 解除VBO
glDeleteBuffers(2,m_VBO);
// 解除VAO
glDeleteVertexArrays(2,m_VAO);
VAO
、VBO
的数据关联绑定,代码如下:// 绑定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);
VAO
的切换,如下:glBindVertexArray(m_VAO[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindVertexArray(m_VAO[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);