之前做了两个同时闪烁的三角形,是通过两个vao对象分别绘制三角形达到闪烁的效果的。那么如果将顶点的颜色属性作为顶点着色器的输出并作为片段着色器的输入,那么就能够分别对每个顶点的颜色单独绘制了,这样就能够使得每个顶点的颜色都不一样。
那么如何使每个顶点闪烁起来呢?那么可以通过uniform来改变片段着色器中颜色变量中的某个值,比如只改变RGBA中的R值。
代码:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(640, 480, "Rectangle", nullptr, nullptr);
glfwMakeContextCurrent(window);
std::cout << glGetString(GL_VERSION) << std::endl;
glewInit();
unsigned int vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
std::vector<float> vertices = {
-0.5f, -0.5f, 1.0f, 0.0f, 0.0f,// 0
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,// 1
0.5f, 0.5f, 0.0f, 0.0f, 1.0f,// 2
-0.5f, 0.5f, 1.0f, 1.0f, 0.0f // 3
};
unsigned int vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*) (2 * sizeof(float)));
std::vector<int> indices = {
0, 1, 2,
2, 3, 0
};
unsigned int ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
const char* vertexShaderSource = "#version 330 core\n"
"layout(location = 0) in vec4 pos;\n"
"layout(location = 1) in vec4 color;\n"
"out vec4 our_color;\n"
"void main()\n"
"{\n"
" gl_Position = pos;\n"
" our_color = color;\n"
"}\0";
unsigned int vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertexShaderSource, nullptr);
glCompileShader(vs);
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"in vec4 our_color;\n"
"uniform float r;\n"
"void main()\n"
"{\n"
" color = vec4(r, our_color[1], our_color[2], our_color[3]);\n"
"}\0";
unsigned int fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragmentShaderSource, nullptr);
glCompileShader(fs);
unsigned int program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
int location = glGetUniformLocation(program, "r");
glBindVertexArray(0);
float increment = 0.05f, r = 0.1f;
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
while (!glfwWindowShouldClose(window))
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
glUseProgram(program);
glUniform1f(location, r);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
glfwSwapBuffers(window);
glfwPollEvents();
if (r > 1) increment = -0.05f;
else if (r < 0) increment = 0.05f;
r += increment;
}
glDeleteProgram(program);
glfwTerminate();
return 0;
}
效果: