《Learn OpenGL》 Ch 01 Hello Window
本部分的实现代码,见 01_CreateWindow
在 Ch 00 Creating a Window 的最后,我们通过一系列代码绘制出了一个纯色的面板,但并没有解释相关的代码。在这一章中,我们将从 0 逐步解释这些代码。
#引入相关库
1 |
#初始化GLFW
在 main 函数的最开始,初始化 GLFW 库,后续将使用 GLFW 来创建窗口。
1 | glfwInit(); |
glfwWindowHint函数的第一个参数用来表示要设定的参数,所有参数都是以GLFW_开头,函数的第二个参数是需要设定的值。 glfwWindowHint接受的参数与参数值,可以在GLFW文档中设置。
#创建GLFW窗口
1 | GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); |
通过glfwCreateWindow函数创建窗口,前两个参数设置窗口的宽和高,第三个参数设置窗口名,最后两个参数教程中未做解释。该函数会返回一个GLFWWINDOW类型的指针。
glfwMakeContextCurrent将glfwCreateWindow返回的表示窗口的指针绑定给当前线程环境。
#初始化GLAD
1 | if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) |
GLAD用来管理OpenGL函数的地址,因此在调用任何的OpenGL函数前需要先对GLAD进行初始化。
需要给gladLoadGLLoader指定读取函数地址的函数,函数地址是系统相关的。在绑定了窗口后,可以通过glfwGetProcAddress函数获取到相应系统给出的函数地址。
因此需要先初始化GLFW,绑定GLFW窗口,再初始化GLAD,然后才能使用OpenGL相应的函数。
#渲染循环
此时在主函数中,就可以设置渲染循环,在其中只要 glfwWindowShouldClose 不返回 true,就意味着窗口不应该被关闭。当窗口不关闭时,就需要进行一系列的渲染操作。
1 | while (!glfwWindowShouldClose(window)) |
glClearColor设置ClearColor的颜色。
glClear设置需要清理的对象,这里仅清理颜色缓存。
glfwSwapBuffers设置双缓冲。如果仅使用单缓存时可能会有图像闪烁的原因,因为图像并不是瞬间被画出,而是从左至右,从下至上逐像素画出。为避免这种情况的发生,可以用双缓存,当前缓存在显示时,后缓存进行读取,当后缓存读完,交换前后缓存,如此,图像可瞬间画出。
glfwPollEvents用来检查是否有事件触发,包括键盘事件,鼠标事件,和窗口事件等。(即使不需要处理输入,也仍然要设定该函数)。
#按键处理
设置函数 processInput 处理按键信息:
1 | void processInput(GLFWwindow *window) |
glfwGetKey用来获取当前窗口按下的按键。 glfwSetWindowShouldClose设置当前窗口需要被关闭,调用该函数后,窗口会被关闭。
processInput函数需要在函数主循环中被调用,保证一直检查输入状态。
在渲染循环 的最开始调用 processInput 函数,保证在渲染前处理的按键信息:
1 | while (!glfwWindowShouldClose(window)) { |
#Viewport设置
当缩放窗口时,需要重新调用 glViewport 以保证渲染的范围与窗口的大小匹配。
为做到这一点,我们定义函数 framebuffer_size_callback 作为窗口大小改变时的回调函数,在回调中通过 glViewport 函数设置视口:
1 | void framebuffer_size_callback(GLFWwindow *window, int width, int height) |
通过 glfwSetFramebufferSizeCallback 将函数 framebuffer_size_callback 设置为窗口大小改变时的回调函数。因为注册回调只需要一次,因此将其放在渲染循环前:
1 | glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); |
#终止GLFW
在主函数的最后,调用 glfwTerminate 关闭窗口:
1 | int main() |

