对应的opengl教程:高级GLSL
uniform缓冲就是申请一个uniform缓冲对象,将要使用到的重复数据储存起来,便于为多个着色器提供uniform输入变量。
老样子上代码:
Uniform_buffer_vertShader.vert
#version 330 core
layout (location=0) in vec3 aPos;
layout(std140)uniform Matrices//std140是表示该结构体使用的std140这种布局方式
{
mat4 projMat;
mat4 viewMat;
};
uniform mat4 modelMat;
void main()
{
gl_Position=projMat*viewMat*modelMat*(vec4(aPos,1.0f));
}
Uniform_buffer_fragment.frag
#version 330 core
out vec4 FragColor;
uniform vec3 color;
void main()
{
FragColor=vec4(color,1.0f);
}
前序工作
//创建shader对象
Shader shaderRed = Shader("Uniform_buffer_vertShader.vert", "Uniform_buffer_fragment.frag");
Shader shaderGreen = Shader("Uniform_buffer_vertShader.vert", "Uniform_buffer_fragment.frag");
Shader shaderBlue = Shader("Uniform_buffer_vertShader.vert", "Uniform_buffer_fragment.frag");
Shader shaderYellow = Shader("Uniform_buffer_vertShader.vert", "Uniform_buffer_fragment.frag");
//拿到对应的块索引
unsigned int uniformBlockIndexRed = glGetUniformBlockIndex(shaderRed.ID, "Matrices");
unsigned int uniformBlockIndexGreen = glGetUniformBlockIndex(shaderGreen.ID, "Matrices");
unsigned int uniformBlockIndexBlue = glGetUniformBlockIndex(shaderBlue.ID, "Matrices");
unsigned int uniformBlockIndexYellow = glGetUniformBlockIndex(shaderYellow.ID, "Matrices");
//给对应的shader绑定上对应的uniform块
glUniformBlockBinding(shaderRed.ID, uniformBlockIndexRed, 0);
glUniformBlockBinding(shaderGreen.ID, uniformBlockIndexGreen, 0);
glUniformBlockBinding(shaderBlue.ID, uniformBlockIndexBlue, 0);
glUniformBlockBinding(shaderYellow.ID, uniformBlockIndexYellow, 0);
//申请uniform缓冲
unsigned int uboMatrices;
glGenBuffers(1, &uboMatrices);
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), NULL, GL_STATIC_DRAW);//申请两个mat4的空间
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBufferRange(GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4));//设置大小
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
//填充projMat
glm::mat4 projMat;//摄像机角度和前后剪切面大小
projMat = glm::perspective(glm::radians(45.0f), (float)WIDTH / (float)HEIGHT, 0.01f, 100.0f);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(projMat));//将0-sizeof(glm::mat4)之间填充上projMat
glBindBuffer(GL_UNIFORM_BUFFER, 0);
//设置颜色,位置和Shader数组
glm::vec3 colors[] = { glm::vec3(1.0f,0.0f,0.0f),glm::vec3(0.0f,1.0f,0.0f),glm::vec3(0.0f,0.0f,1.0f),glm::vec3(1.0f,1.0f,0.0f) };
glm::vec3 newCubePos[] = { glm::vec3(-1.0f,1.0f,0.0f),
glm::vec3(-1.0f,-1.0f,0.0f),
glm::vec3(1.0f,1.0f,0.0f),
glm::vec3(1.0f,-1.0f,0.0f) };
Shader myShader[] = { shaderRed,shaderGreen,shaderBlue,shaderYellow };
视角矩阵绑定
//设置view矩阵
viewMat = myCamera->GetViewMatrix();
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4),sizeof(glm::mat4), glm::value_ptr(viewMat));
glBindBuffer(GL_UNIFORM_BUFFER, 0);
绘制这四个立方体
glBindVertexArray(cubeVAO);
//绘制立方体
for (size_t i = 0; i < 4; i++)
{
glm::mat4 modelMat;//模型矩阵就是前面的变换矩阵
modelMat = glm::translate(modelMat, newCubePos[i]);
myShader[i].Use();
myShader[i].setVec3("color",colors[i]);
myShader[i].setMat4("modelMat",modelMat);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
最终效果: