OpenGL学习笔记(一)——你好,三角形(结构简化,详细注释)

学习网址

https://learnopengl-cn.readthedocs.io/zh/latest/01%20Getting%20started/04%20Hello%20Triangle/

#include<iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW\glfw3.h>

using namespace std;
//着色器源码
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";

GLuint VBO;		//顶点缓冲对象	vertex buffer object
GLuint VAO;		//顶点数组对象	vertex array object
GLuint EBO;		//索引缓冲对象	element buffer object
GLuint shaderProgram;

GLfloat vertexes[] = {
	 0.5f,  0.5f, 0.0f,  // Top Right
	 0.5f, -0.5f, 0.0f,  // Bottom Right
	-0.5f, -0.5f, 0.0f,  // Bottom Left
	-0.5f,  0.5f, 0.0f   // Top Left 
};
GLuint indexes[] = {
	0,1,3,
	1,2,3,
};

void key_exit(GLFWwindow* window, int key, int scancode, int action, int mode) {
	if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
		glfwSetWindowShouldClose(window, GL_TRUE);
}

void initWindow(GLFWwindow* window) {
	if (window == nullptr) {
		cout << "failed to create window" << endl;
		glfwTerminate();
	}
	glfwMakeContextCurrent(window);
	int w, h;
	glfwGetFramebufferSize(window, &w, &h);		//不直接使用800,600,是为了使之能在高DPI屏幕运行
	glViewport(0, 0, w, h);
}

void initGLFW() {
	glfwInit();														//初始化窗口
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);					//设置主版本号为3
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);					//设置次版本号为3
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);	//启用核心模式
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);						//禁止调整窗口大小
}
void initGLEW() {
	glewExperimental = GL_TRUE;										//开启现代OpenGL功能
	if (glewInit() != GLEW_OK) 
		cout << "failed to initialize glew!" << endl;	
}

void initShader() {

	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);			//创建顶点着色器		
	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);		//加载顶点着色器代码
	glCompileShader(vertexShader);									//编译顶点着色器代码

	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);		//创建片段着色器
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);	//加载片段着色器代码
	glCompileShader(fragmentShader);								//编译片段着色器代码

    shaderProgram = glCreateProgram();								//创建着色器程序
	glAttachShader(shaderProgram, vertexShader);					//添加着色器
	glAttachShader(shaderProgram, fragmentShader);						
	glLinkProgram(shaderProgram);									//链接程序							
	glDeleteShader(vertexShader);									//销毁着色器
	glDeleteShader(fragmentShader);
}

void initData() {
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);					//给VBO分配一个单位的缓冲对象,VBO会被赋值一个对象id,每调用一次glGenBuffer,这个id会加1
	glGenBuffers(1, &EBO);

	glBindVertexArray(VAO);					//绑定VAO,之后所有的顶点属性调用都会存储到VAO中

	glBindBuffer(GL_ARRAY_BUFFER, VBO);		//指定array buffer的操作对象为VBO
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), vertexes, GL_STATIC_DRAW);	//导入顶点数据,gl static draw采用静态的数据处理方式(当数据不会变动时使用)
	
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexes), indexes, GL_STATIC_DRAW);

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);	//设置顶点解析格式
	
	glEnableVertexAttribArray(0);		//以顶点属性位置值作为参数,启用顶点属性

	glBindBuffer(GL_ARRAY_BUFFER, 0);	// 解绑VBO

	glBindVertexArray(0);				// 解绑VAO

}

int main(){	
	initGLFW();									//初始化GLFW
	GLFWwindow* window= glfwCreateWindow(800, 600, "hello GL!", nullptr, nullptr);
	initWindow(window);							//初始化窗口
	
	glfwSetKeyCallback(window, key_exit);		//设置键盘回调函数
	
	initGLEW();									//初始化GLEW

	initShader();								//初始化着色器

	initData();									//初始化顶点数据

	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);		//设置清屏颜色

	while (!glfwWindowShouldClose(window)) {	//图像绘制
		glfwPollEvents();				//检查并处理事件
		glClear(GL_COLOR_BUFFER_BIT);
		glUseProgram(shaderProgram);	//设置着色程序
		glBindVertexArray(VAO);			//绑定VAO
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);	//解析顶点数据
		glBindVertexArray(0);			//解绑VAO
		glfwSwapBuffers(window);		//交换缓冲
	}

	glDeleteVertexArrays(1, &VAO);		//销毁对象
	glDeleteBuffers(1, &VBO);
	glDeleteBuffers(1, &EBO);
	glfwTerminate();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40946921/article/details/104460601