一、颜色
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
layout(location = 2) in vec2 aTexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
};
#version 330 core
out vec4 fragColor;
uniform vec4 vexColor;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform vec3 lightColor;
uniform vec3 objectColor;
void main()
{
fragColor = vec4(lightColor*objectColor,1.0f);
}
#version 330 core
layout(location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
};
#version 330 core
out vec4 fragColor;
void main()
{
fragColor = vec4(1.0,1.0,1.0,1.0);
}
- 因为shader不同,所以需要对这两部分分别做shader以及program的操作,在本文中便是定义两个不同的Shader对象。
Shader ourShader("res/shader/cubeVertex.shader", "res/shader/cubeFragment.shader");
Shader lightShader("res/shader/lightVertex.shader", "res/shader/lightFragment.shader");
- 两个部分都是使用立方体,所以VBO与EBO可以共享,但是VAO需要分别设置,因为VAO包含着节点指针函数,这与shader的输入变量相关。对于VBO与EBO的数据,自然也是只需要一次传输。
unsigned int VBO;
glGenBuffers(1, &VBO);
unsigned int EBO;
glGenBuffers(1, &EBO);
unsigned int lightVAO;
glGenVertexArrays(1, &lightVAO);
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindVertexArray(lightVAO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
- 在绘制的时候,对这两个物体需要进行两次流程,相应的program、VAO、以及绘制图形(比如节点数量等)均不同,需要按照自己的需求来设置。
- 相应的,对program的uniform操作也各不相同。
- 此外,另一个重要的地方是,二者的view matrix和projection matri是一样的,因此只需要定义一次而公用,但是model matrix显然是不一样的。
ourShader.use();
ourShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);
ourShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
glBindVertexArray(VAO);
glm::mat4 view = camera.ViewMatrix();
ourShader.setMat4("view", glm::value_ptr(view));
glm::mat4 projection = glm::perspective(glm::radians(camera.Fov), (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.1f, 100.0f);
ourShader.setMat4("projection", glm::value_ptr(projection));
for (int i = 0; i != 10; i++)
{
glm::mat4 model;
model = glm::translate(model, cubePositions[i]);
float angle = 20.0f * (i+1);
model = glm::rotate(model, (float)glfwGetTime() * glm::radians(angle), glm::vec3(0.0f, 1.0f, 1.0f));
ourShader.setMat4("model", glm::value_ptr(model));
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
}
lightShader.use();
glBindVertexArray(lightVAO);
glm::vec3 lightPos = glm::vec3(0.0f, 1.0f, 0.0f);
glm::mat4 lightModel;
lightModel = glm::translate(lightModel, lightPos);
lightModel = glm::scale(lightModel, glm::vec3(0.2f, 0.2f, 0.2f));
lightShader.setMat4("model", glm::value_ptr(lightModel));
lightShader.setMat4("view", glm::value_ptr(view));
lightShader.setMat4("projection", glm::value_ptr(projection));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
