OpenGL学习(二)——GLFW
参考资料:
- 【双语】【TheCherno】OpenGL_哔哩哔哩_bilibili
- [LearnOpenGL CN (learnopengl-cn.github.io)](https://learnopengl-cn.github.io/01 Getting started/02 Creating a window/)
- LearnOpenGL 示例环境搭建 - 知乎 (zhihu.com)
创建窗口
[你好,窗口 - LearnOpenGL CN (learnopengl-cn.github.io)](https://learnopengl-cn.github.io/01 Getting started/03 Hello Window/)
窗口对象
GLFWwindow对象封装了窗口和上下文。它们是用glfwCreatewindow
创建的,用glfwDestroyWindow
或者glfwTerminate
销毁。
窗口创建
窗口及其OpenGL上下文是用glfwCreateWindow
函数创建的,它返回创建的窗口对象的句柄。
例如,创建一个窗口模式(windowed mode)下640*480的窗口,执行以下代码:
GLFWwindow* window = glfwCreateWindow(640, 480, “My Title”, NULL, NuLL);
如果窗口创建失败,将返回NULL。
全屏窗口覆盖显示器的整个显示区域,没有边框或装饰。要创建全屏窗口(Full screen windows),执行以下代码:
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonitor(), NULL);
使用glfwSetWindowMonitor
函数设置显示器可以使窗口模式变为全屏显示,取消设置的话可以使全屏显示转换为窗口显示。
窗口销毁
当不再需要一个窗口时,用glfwDestroyWindow
销毁该窗口。
glfwDestroyWindow(window);
在销毁窗口之前,所有的回调函数都被移除,因此不会再为该窗口传递任何事件。当调用glfwTerminate
时,所有剩余的窗口也被销毁。
窗口Hint
创建窗口和上下文之前,可以设置许多Hint
。有些影响窗口本身,有些影响帧缓冲区或上下文。:
-
glfwWindowHint():单独设置整数值提示。
-
glfwWindowHintString():单独设置字符串值提示。
-
glfwDefaultWindowHints():一次将所有提示重置为默认值。
这些提示分为窗口相关提示(Window related hints),帧缓冲区相关提示(Framebuffer related hints),显示器相关提示(Framebuffer related hints),以及上下文相关提示(Context related hints)。
实例化GLFW窗口
了解了一些基本的GLFW的窗口相关功能之后,就可以开始创建GLFW窗口了。
#include <glad/glad.h>//GLAD头文件包含了OpenGL头文件,所以在使用其它依赖于OpenGL的头文件之前要先包含GLAD
#include <GLFW/glfw3.h>
int main()
{
glfwInit();//初始化GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//主版本号,当API以不兼容的方式更改时,该值会增加。
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//次版本号,当特性被添加到API中时,它会增加,但是它保持向后兼容。
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//使用核心模式
return 0;
}
glfwInit()与glfwTerminate()
-
glfwInit()
:必须先初始化GLFW。并且在应用程序退出之前调用glfwTerminate()
。 -
glfwTerminate()
:释放分配的资源。调用此函数后,必须再次成功调用glfwInit()
,才能使用GLFW函数。
glfwCreateWindow函数
该函数创建一个窗口及其相关的OpenGL或OpenGL ES上下文,完整函数名如下:
GLFWwindow * glfwCreateWindow (int width, //以屏幕坐标表示的窗口的期望宽度,必须大于零。
int height, //以屏幕坐标表示的窗口期望高度,必须大于零。
const char * title,//窗口标题。
GLFWmonitor * monitor,//用于全屏模式的monitor,对于窗口模式为NULL。
GLFWwindow * share //要与其共享资源的上下文的窗口,值为NULL表示不共享资源。
)
了解了上面几个基础函数之后,我们开始创建一个窗口对象,这个窗口对象存放了所有和窗口相关的数据。
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);//窗口的宽,高,名称,...,...
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
初始化GLAD
GLAD是用来管理OpenGL的函数指针的,所以我们先需要初始化GLAD,再调用OpenGL的函数。
//给GLAD传入了用来加载系统相关的OpenGL函数指针地址的函数。
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
视口(Viewport)
设置视口,来规定OpenGL渲染窗口的尺寸大小,这样OpenGL才只能知道怎样根据窗口大小显示数据和坐标。
我们可以通过调用glViewport
函数来设置窗口的维度(Dimension):
glViewport(0, 0, 800, 600);//前两个参数控制窗口左下角的位置,第三个和第四个参数控制渲染窗口的宽度和高度。
OpenGL幕后使用glViewport中定义的位置和宽高进行2D坐标的转换,将OpenGL中的位置坐标转换为你的屏幕坐标。处理过的OpenGL坐标范围只为-1到1。
例如,OpenGL中的坐标(-0.5, 0.5)可能最终被映射为屏幕中的坐标(200,450)。因此我们事实上将(-1到1)范围内的坐标映射到(0, 800)和(0, 600)。
添加事件回调
需要在创建窗口之后,渲染循环初始化之前注册事件回调函数。
窗口大小回调
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
每当窗口改变大小,GLFW会调用这个函数并填充相应的参数供你处理。
键盘输入回调
使用glfwGetKey函数实现输入控制,会返回这个按键是否正在被按下。
void processInput(GLFWwindow *window){
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true); //按下ESC,关闭GLFW
}
渲染循环(Render Loop)
在我们让GLFW退出前一直保持运行,从而不断绘制图像并接受用户输入。
while (!glfwWindowShouldClose(window))//glfwWindowShouldClose函数在每次循环开始前检查一次GLFW是否被要求退出,如果是的话该函数返回true,渲染循环结束。
{
processInput(window);//循环每次迭代时调用该函数,检测用户是否输入ESC键
//渲染指令
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//清除颜色设置为X色
glClear(GL_COLOR_BUFFER_BIT);//清屏动作
//检查并调用事件,交换缓冲
glfwSwapBuffers(window);//glfwSwapBuffers函数会交换颜色缓冲(储存着GLFW窗口每一个像素颜色值的大缓冲),它在这一迭代中被用来绘制,并且将会作为输出显示在屏幕上。
glfwPollEvents();//glfwPollEvents函数检查是否触发事件(比如键盘输入、鼠标移动)、更新窗口状态,并调用对应地回调函数(可以通过回调方法手动设置)
}
glfwWindowShouldClose
函数在我们每次循环的开始前检查一次GLFW是否被要求退出,如果是的话该函数返回true
然后渲染循环便结束了,之后为我们就可以关闭应用程序了。glfwPollEvents
函数检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)。glfwSwapBuffers
函数会交换缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲),即实现双缓冲的翻页
清屏
每轮渲染开始时都应该清屏,这样就能去掉上一次的渲染结果。
glClear
函数:清空屏幕的颜色缓冲,它接受一个缓冲位(Buffer Bit)来指定要清空的缓冲:
-
GL_COLOR_BUFFER_BIT
-
GL_DEPTH_BUFFER_BIT
-
GL_STENCIL_BUFFER_BIT
glClearColor
函数:设置用于清屏的颜色,即用这个颜色来涂满屏幕,不设置的话就是用黑色清屏,清完屏幕就得到一片全黑。
标签:窗口,函数,OpenGL,GLFWwindow,学习,window,GLFW From: https://www.cnblogs.com/3to4/p/17996544可以发现,glClearColor函数是一个状态设置函数,而glClear函数则是一个状态使用的函数