学习链接:你好,窗口
本课目标:
利用GLFW和GLAD创建一个渲染了颜色并且监听到按了esc键就退出的窗口。
整体思路
- 初始化
GLFW - 通过
GLFW创建窗口并设置上下文 - 通过
GLFW添加窗口大小变化的回调,在回调中设置OpenGL的视口 - 通过
GLAD加载OpenGL所有的函数的指针 - 开启渲染循环,每个迭代中处理输入事件、渲染、交换缓冲区、获取输入事件
- 结束循环,释放资源,退出程序
知识点
- 先include GLAD的头文件,因为GLAD的头文件包含了OpenGL头文件,所以需要在其它依赖于OpenGL的头文件之前包含GLAD。
- mac os需要额外调用
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE) - OpenGL展示图像需要上下文和窗口,OpenGL将这些进行抽象,不同系统需要自己提供不同的实现,需要开发者自己处理
- GLFW可以帮助开发者实现不同系统的上下文、窗口管理及输入事件的处理
- OpenGL是一个规范,具体的实现者是显卡驱动,由于版本繁多,具体的OpenGL函数实现位置很难在编译时期确定,那就需要在运行时定位具体的函数位置并保存在函数指针中以供后续使用
- GLAD可以帮助开发者查询OpenGL函数的位置并加载,之后开发者可以正常调用OpenGL的函数
完整代码
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
**void** framebuffer_size_callback(GLFWwindow* window, **int** width, **int** height);
**void** processInput(GLFWwindow *window);
// settings
**const** **unsigned** **int** SCR_WIDTH = 800;
**const** **unsigned** **int** SCR_HEIGHT = 600;
**int** main()
{
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// glfw window creation
// --------------------
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", **NULL**, **NULL**);
**if** (window == **NULL**)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
**return** -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// glad: load all OpenGL function pointers
// ---------------------------------------
**if** (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
**return** -1;
}
// render loop
// -----------
**while** (!glfwWindowShouldClose(window))
{
// input
// -----
processInput(window);
// render
// ------
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
glfwTerminate();
**return** 0;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
**void** processInput(GLFWwindow *window)
{
**if**(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, **true**);
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
**void** framebuffer_size_callback(GLFWwindow* window, **int** width, **int** height)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}