在多个shader中可能使用相同的uniform变量,比如projection和view矩阵,此时多次填入数据较为麻烦。利用uniform缓冲就可实现多个shader共用uniform数据。
首先在shader程序中写好uniform接口块
注意接口块最后是有分号的
#version 330 core
layout (location = 0) in vec3 aPos;layout (std140) uniform Matrices
{mat4 projection;mat4 view;
};
uniform mat4 model;void main()
{gl_Position = projection * view * model * vec4(aPos, 1.0);
}
然后是我们将顶点着色器的Uniform块设置为绑定点0
unsigned int uniformBlockIndexRed = glGetUniformBlockIndex(shaderRed.ID, "Matrices");
unsigned int uniformBlockIndexGreen = glGetUniformBlockIndex(shaderGreen.ID, "Matrices");glUniformBlockBinding(shaderRed.ID, uniformBlockIndexRed, 0);
glUniformBlockBinding(shaderGreen.ID, uniformBlockIndexGreen, 0);
接下来,我们创建Uniform缓冲对象本身,并将其绑定到绑定点0:
unsigned int uboMatrices
glGenBuffers(1, &uboMatrices);glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), NULL, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);glBindBufferRange(GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4));
最后就是将矩阵数据填入其中,这里用的是glBufferSubData函数,所以要注意uniform块中变量的顺序对应其偏移量。
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)width/(float)height, 0.1f, 100.0f);
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(projection));
glBindBuffer(GL_UNIFORM_BUFFER, 0);