首页 > 其他分享 >OpenGL学习(二)——GLFW

OpenGL学习(二)——GLFW

时间:2024-01-30 10:23:19浏览次数:29  
标签:窗口 函数 OpenGL GLFWwindow 学习 window GLFW

OpenGL学习(二)——GLFW

参考资料:

创建窗口

[你好,窗口 - 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函数:设置用于清屏的颜色,即用这个颜色来涂满屏幕,不设置的话就是用黑色清屏,清完屏幕就得到一片全黑。

可以发现,glClearColor函数是一个状态设置函数,而glClear函数则是一个状态使用的函数

标签:窗口,函数,OpenGL,GLFWwindow,学习,window,GLFW
From: https://www.cnblogs.com/3to4/p/17996544

相关文章

  • OpenGL学习(三)——GLSL
    OpenGL学习(三)——GLSL参考资料:【双语】【TheCherno】OpenGL_哔哩哔哩_bilibili[LearnOpenGLCN(learnopengl-cn.github.io)](https://learnopengl-cn.github.io/01Gettingstarted/02Creatingawindow/)LearnOpenGL示例环境搭建-知乎(zhihu.com)GLSL着色器(Shad......
  • Power BI - 5分钟学习创建合并列
    每天5分钟,今天介绍PowerBI如何创建合并列什么是合并列顾名思义合并列就是把两个列信息拼接到一个列中显示。工作中经常会有类似需求,把产品编码和产品名称放到一个筛选器或者单元格中展示。那我们在PowerBI中应该如何进行类似创建合并列的操作呢?首先导入样例产品表;(Excel数据......
  • 非内积级联学习
    1.首页推荐非内积召回现状非内积召回源是目前首页推荐最重要的召回源之一。同时非内积相比于向量化召回最终仅将user和item匹配程度表征为embeding内积,非内积召回仅保留itemembedding,不构造user显式表征,而是通过一个打分网络计算用户-商品匹配程度,极大的提升了模型精准度的上限,......
  • Unity3D DrawCall和openGL、光栅化等有何内在联系详解
    Unity3D是一款跨平台的游戏引擎,广泛应用于游戏开发领域。在Unity3D中,DrawCall是一个重要的概念,它与OpenGL、光栅化等技术有着密切的内在联系。本文将详细解释DrawCall的概念,并给出相关技术的详细解释和代码实现。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础......
  • 寒假学习15
    今天接着学习声音转换训练: 点击脚本可以查看转换进度: http://localhost:6006/在转换声音数据的时候显示错误 问了问gpt:还是无法解决。......
  • ControlNet学习实战1--字体海报
    最近玩AI绘画的过程中,突然发现了一个可以生成特点字体海报的技巧,特此记录学习一下。本片文章介绍大家制作一张2024龙年海报。ControlNet介绍ControlNet是一个应用于Stable_diffusion一个插件,该插件可以让AI更加精准的生成准确的想要的图片,关于这些内容后期会专门更加细致的说明......
  • Java学习(day1)
    注释单行注释`//publicclass多行注释/*publicclasshellopvsm*/文档注释~~~(没啥用)/**213213**/标识符首字符可以字母、下划线、美元符(不能是数字和其他符号)StringAhello="Q";Stringheloo="Q";String$he="Q";String_hello="Q";大小写敏感......
  • 大三寒假学习进度笔记20
    今日对LangChain进行了一些了解。LangChain是一个强大的框架,旨在帮助开发人员使用语言模型构建端到端的应用程序。它提供了一套工具、组件和接口,可简化创建由大型语言模型(LLM)和聊天模型提供支持的应用程序的过程。LangChain可以轻松管理与语言模型的交互,将多个组件链接在一......
  • 【实战项目】想自己通过C语言编写贪吃蛇吗?先来学习一下什么是WIN32API
    WIN32API前言大家好,很高兴又和大家见面了!!!在开始今天的内容前,咱们先闲聊一下。博主是从2023.8.19号晚上23:28左右正式开始接触C语言,在此之前,我也只是一个对编程一窍不通的小白,我的本科专业是给排水科学与工程,一个就业前景还不错但是不太适合我本人的专业。在经历了一些事情之后,我......
  • 李宏毅《机器学习》总结 - RNN & LSTM
    在slot-filling问题(如给一个句子,自己分析出时间、地点等)如果只连着不同的FC,那么会导致无法读出是arrive还是leave的情况,导致错误因此,需要NN来考虑到整个句子的信息,也就是需要有memory,这就是RNNRNN原理有了memory,就可以初步解决同一个信息由于句子不同导致的意......