第一个OpenGL程序

因为对计算机图形学不了解,所以准备学习一下计算机图形学的知识,对照着网课上老师的讲解,完成了第一个OpenGL程序:绘制三角形 

绘制三角形

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>

// 去掉控制台窗口
//#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

int main() {
	void framebuffer_size_callback(GLFWwindow* window, int width, int height);
	void processInput(GLFWwindow* window);


	// 初始化GLFW
	glfwInit();

	// 配置GLFW 第一个参数:选项名称,第二个参数:选项的值
	// 因为使用的是OpenGL3.3 ,所以主版本号(Major)和此版本号(Minor)都设为3,指定使用的是核心模式(Core-profile)
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	// 设置是否可以改变窗口大小
	glfwWindowHint(GLFW_RESIZABLE, false);

	// Mac系统需要加上这一行
	//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 

	// 创建窗口
	int width = 800;
	int height = 600;
	GLFWwindow* window = glfwCreateWindow(width, height, "OpenGL", NULL, NULL);

	// 判断窗口是否创建成功
	if (window == NULL) {
		std::cout << "Failed to create GLFW window" << std::endl;
		// 终止
		glfwTerminate();
		return -1;
	}

	// 将窗口的上下文设置为当前线程的主上下文
	// 上下文是指OpenGL当前的状态(OpenGL本身是一个大的状态机)
	glfwMakeContextCurrent(window);

	// 初始化GLAD,加载OpenGL函数指针地址的函数
	// GLAD是用来管理OpenGL函数指针
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	// 指定当前视口尺寸
	glViewport(0, 0, width, height);

	// --数据处理:生成和绑定VBO和VAO,设置属性指针
	// 三角形的顶点数据
	const float triangle[] = {
		// ---- 位置 ----
		-0.5f, -0.5f, 0.0f,	// 左下
		0.5f, -0.5f, 0.0f,	// 右下
		0.0f, 0.5f, 0.0f	// 正上
	};

	// 生成并绑定立方体的VAO和VBO
	GLuint vertex_array_object;	// VAO
	glGenVertexArrays(1, &vertex_array_object);
	glBindVertexArray(vertex_array_object);
	GLuint vertex_buffer_object;	// VBO
	glGenBuffers(1, &vertex_buffer_object);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object);
	// 将顶点数据绑定至当前默认的缓冲中
	glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);

	// 设置顶点属性指针
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	// --

	// 顶点着色器的源码和片段着色器的源码 GLSL语言编写
	const char *vertex_shader_source =
		"#version 330 core\n"	// 使用OpenGL3.3核心模式
		"layout(location = 0) in vec3 aPos;\n"	// 位置变量的属性位置值为0
		"void main()\n"
		"{\n"
		"	gl_Position = vec4(aPos,1.0);\n"
		"}\n\0";
	const char *fragment_shader_source =
		"#version 330 core\n"
		"out vec4 FragColor;\n"	// 输出的颜色向量
		"void main()\n"
		"{\n"
		"	FragColor = vec4(0.0f,1.0f,0.0f,1.0f);\n"
		"}\n\0";

	// 生成并编译着色器
	// 顶点着色器
	int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
	glCompileShader(vertex_shader);
	int success;
	char info_log[512];
	// 检查着色器是否成功编译,如果编译失败,打印错误信息
	glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
	if (!success) {
		glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << info_log << std::endl;
	}

	// 生成并编译着色器
	// 片段着色器
	int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
	glCompileShader(fragment_shader);
	// 检查着色器是否成功编译,如果编译失败,打印错误信息
	glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
	if (!success) {
		glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << info_log << std::endl;
	}

	// 链接顶点和片段着色器至一个着色器程序
	int shader_program = glCreateProgram();
	glAttachShader(shader_program, vertex_shader);
	glAttachShader(shader_program, fragment_shader);
	glLinkProgram(shader_program);
	// 检查着色器是否成功链接,如果链接失败,打印错误信息
	glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
	if (!success) {
		glGetProgramInfoLog(shader_program, 512, NULL, info_log);
		std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << info_log << std::endl;
	}

	// 删除着色器,后面渲染只需要使用链接好的着色器程序
	glDeleteShader(vertex_shader);
	glDeleteShader(fragment_shader);

	//glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	while (!glfwWindowShouldClose(window))
	{
		//processInput(window);

		// 清空颜色缓冲
		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		// 使用着色器程序
		glUseProgram(shader_program);

		// 绘制三角形
		glBindVertexArray(vertex_array_object);	// 绑定VAO
		glDrawArrays(GL_TRIANGLES, 0, 3);	// 绘制三角形
		glBindVertexArray(0);	// 解除绑定
		
		// 交换缓冲并且检查是否有触发事件(比如键盘,鼠标移动)
		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	// --窗口关闭时的善后工作
	// 删除VAO和VBO
	glDeleteVertexArrays(1, &vertex_array_object);
	glDeleteBuffers(1, &vertex_buffer_object);

	// 清理所有资源并正确退出程序
	glfwTerminate();
	return 0;
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
	glViewport(0, 0, width, height);
}

void processInput(GLFWwindow* window) {
	
}

运行效果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值