这段代码是一个使用 OpenGL 和 GLFW 创建窗口并绘制简单三角形的基本程序。下面是逐行解析:
头文件
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
glad/glad.h
: 用于加载 OpenGL 函数指针。GLFW/glfw3.h
: 用于创建窗口和处理输入。<iostream>
: C++ 的输入输出流库,用于打印调试信息。
顶点数据
float vertices[] = {
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.0f,0.5f,0.0f
};
定义了一个三角形的三个顶点,每个顶点由 x, y, z 三个坐标组成。
输入处理函数
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
这个函数用于检测用户是否按下了 ESC 键,如果按下,则关闭窗口。
主函数
int main() {
glfwInit(); // 初始化 GLFW 库
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPEGL_FORWARD_COMPAT, GL_TURE); // macOS 特殊设置(此处有错,应该是 GL_TRUE)
#endif // __APPLE__
GLFWwindow* window = glfwCreateWindow(800, 600, "demo01", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window); // 将上下文设置为当前线程
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { // 加载 OpenGL 函数指针
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
这里初始化了 GLFW 并创建了一个窗口,设置了一些 OpenGL 上下文的版本信息。如果窗口创建失败,则输出错误信息并终止程序。同时,使用 glad 加载 OpenGL 的函数指针。
创建 VBO 和 VAO
unsigned int VBO, VAO;
glGenVertexArrays(1,&VAO); // 生成一个顶点数组对象 VAO
glGenBuffers(1, &VBO); // 生成一个顶点缓冲区对象 VBO
glBindVertexArray(VAO); // 绑定 VAO
glBindBuffer(GL_ARRAY_BUFFER, VBO); // 绑定 VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
这部分代码用于生成和绑定顶点数组对象 (VAO) 和顶点缓冲区对象 (VBO)。glBufferData
用于将数据传输到 GPU。
设置 Vertex Attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glVertexAttribPointer
告诉 OpenGL 如何解析我们在 VBO 中存储的数据。这里的第一个参数是属性位置(对应着 shader 中的位置),第二个参数是每个顶点的组件数量(这里为3,即 x、y、z),第三个参数是数据类型。glEnableVertexAttribArray
启用这个属性。
最后解绑 VBO 和 VAO,以便在之后不小心修改它们。
渲染循环
while (!glfwWindowShouldClose(window)) {
processInput(window); // 检查输入
glClearColor(0.2f , 0.3f , 0.3f , 1.0f ); // 设置清除颜色
glClear(GL_COLOR_BUFFER_BIT); // 清屏
glBindVertexArray(VAO); // 绘制三角形
glDrawArrays(GL_TRIANGLES , 0 , 3 );
glfwSwapBuffers(window); //交换前后缓冲区以显示渲染结果
glfwPollEvents(); // 检测事件(如按键)
}
- 在这个循环中,不断地处理用户输入,然后清屏,并绘制三角形,最后交换前后缓冲区以显示新渲染的内容。
程序结束处理
glfwTerminate();
return 0;
}
当循环结束后,调用 glfwTerminate()
来清理所有资源,并返回程序执行结果。
注意:
- 有一处拼写错误,在 macOS 部分应为
GL_TRUE
而不是GL_TURE
。 - 如果需要真正绘制图形,还需编写相应的 vertex shader 和 fragment shader,并进行编译和链接,但本示例没有包含这一部分。
内容由零声教学AI助手提供,问题来源于学员提问