Modern OpenGL---做一些好玩的东西 01(绘制两个同时闪烁的三角形)

在刚刚学习了现代OpenGL后,想做一些好玩的东西。这是第一个,想做两个三角形,然后这两个三角形的颜色会一直变化,就能达到闪烁的效果。

  1. 绘制两个不同颜色的三角形的话,首先应该将顶点的索引分成两个ibo对象,然后通过两个vao对象来进行绑定,而顶点数据vbo对象可以共用两个,只不过需要在两个vao对象上分别绑定一次;
  2. 不同颜色的三角形,则需要两个不同的片段着色器(疑问:能否只用同一个片段着色器达到两种不同的颜色?),然后分别在不同的FragmentShader中设置不同的颜色,然后在窗口循环中进行渲染时,分别对两个vao进行渲染前使用不同的ShaderProgram以及绑定两个vao对象即可;
  3. 如果想让三角形的颜色变化起来,也就是在每次循环渲染时改变着色器的颜色设置。可以通过uniform来获得两个片段着色器中的颜色变量,然后在着色器程序外部对片段着色器中的颜色变量进行赋值,从而达到每次渲染时颜色变化的效果。

代码如下:(这些代码看起来有点乱,没有抽象化,不符合面向对象编程的风格,但是对于整个OpenGL的渲染管线的理解来说比抽象出来更加容易理解)

#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 vao1;
	glGenVertexArrays(1, &vao1);
	glBindVertexArray(vao1);

	std::vector<float> vertices = {
		-0.5f, -0.5f, // 0
		 0.5f, -0.5f, // 1
		 0.5f,  0.5f, // 2
		-0.5f,  0.5f // 3
	};
	unsigned int vbo;
	glGenBuffers(1, &vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(float), &vertices[0], GL_STATIC_DRAW);

	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

	std::vector<int> indices1 = {
		0, 1, 2
	};
	unsigned int ibo1;
	glGenBuffers(1, &ibo1);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo1);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(unsigned int), &indices1[0], GL_STATIC_DRAW);

	unsigned int vao2;
	glGenVertexArrays(1, &vao2);
	glBindVertexArray(vao2);

	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
	

	std::vector<int> indices2 = {
		2, 3, 0
	};
	unsigned int ibo2;
	glGenBuffers(1, &ibo2);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo2);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(unsigned int), &indices2[0], GL_STATIC_DRAW);
	
	const char* vertexShaderSource = "#version 330 core\n"
		"layout(location = 0) in vec4 pos;\n"
		"void main()\n"
		"{\n"
		"	gl_Position = pos;\n"
		"}\0";
	unsigned int vs = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vs, 1, &vertexShaderSource, nullptr);
	glCompileShader(vs);
	int success;
	glGetShaderiv(vs, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		char message[512];
		glGetShaderInfoLog(vs, 512, nullptr, message);
		std::cout << message << std::endl;
	}
	
	const char* fragmentShaderSource = "#version 330 core\n"
		"out vec4 color;\n"
		"uniform vec4 u_Color;\n"
		"void main()\n"
		"{\n"
		"	color = u_Color;\n"
		"}\0";
	unsigned int fs = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fs, 1, &fragmentShaderSource, nullptr);
	glCompileShader(fs);

	const char* fragmentShaderSource1 = "#version 330 core\n"
		"out vec4 color;\n"
		"uniform vec4 u_Color;\n"
		"void main()\n"
		"{\n"
		"	color = u_Color;\n"
		"}\0";
	unsigned int fs1 = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fs1, 1, &fragmentShaderSource1, nullptr);
	glCompileShader(fs1);

	unsigned int program = glCreateProgram();
	glAttachShader(program, vs);
	glAttachShader(program, fs);
	glLinkProgram(program);
	int result;
	glGetProgramiv(program, GL_LINK_STATUS, &result);
	if (!result)
	{
		char info[512];
		glGetProgramInfoLog(program, 512, nullptr, info);
		std::cout << info << std::endl;
	}

	unsigned int program1 = glCreateProgram();
	glAttachShader(program1, vs);
	glAttachShader(program1, fs1);
	glLinkProgram(program1);

	glUseProgram(program1);
	glDeleteShader(vs);
	glDeleteShader(fs);
	glDeleteShader(fs1);

	glBindVertexArray(0);

	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	int location1 = glGetUniformLocation(program, "u_Color");
	ASSERT(location1 != -1);
	int location2 = glGetUniformLocation(program1, "u_Color");
	ASSERT(location2 != -1);
	float r1 = 0.0f, r2 = 1.0f;
	float increment1 = 0.05f, increment2 = 0.05f;
	while (!glfwWindowShouldClose(window))
	{
		
		glClear(GL_COLOR_BUFFER_BIT);
		glBindVertexArray(vao1);
		glUseProgram(program);
		glUniform4f(location1, r1, 0.2f, 0.8f, 1.0f);
		glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);

		glBindVertexArray(vao2);
		glUseProgram(program1);
		glUniform4f(location2, 0.4f, r2, 0.2f, 1.0f);
		glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
		glfwSwapBuffers(window);
		glfwPollEvents();

		if (r1 > 1)
			increment1 = -0.05f;
		else if (r1 < 0)
			increment1 = 0.05f;
		r1 += increment1;

		if (r2 > 1)
			increment2 = -0.05f;
		else if (r2 < 0)
			increment2 = 0.05f;
		r2 += increment2;

	}
	glDeleteProgram(program);
	glfwTerminate();

	return 0;
}

效果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值