学习OpenGL 二、入门(1)窗口搭建

本文档主要使用glfw和glad进行开发,主要是对文档简介 - LearnOpenGL CN (learnopengl-cn.github.io)的学习笔记

1、环境搭建

本文档主要在vs2022环境下,使用glfw和glad进行开发,在前文中列出了详细的环境配置参考。为了方便使用这里编写了一个简要快速的自用配置方法。在VS022内的程序包外,需依照前文的教程下载好glad。

(1)配置glfw

glfw库选择项目-管理NuGet程序包-浏览-搜索glfw下载即可。

(2)glad配置

将下载好的glad包解压放到项目文件夹中(其实放哪都一样)。下载完成后右键项目,选择属性-C/C++-附加包含目录,输入glad文件夹下的include文件夹所在位置。随后将glad-scr-glad.c文件复制到源文件下。输入头文件不报错那就是没问题。如果打开属性栏里面没有C/C++的属性,在源文件里面新建一个cpp就好了。

两位的头文件:

#include <glad/glad.h>
#include <GLFW/glfw3.h>

基本环境搭建完毕。


2、窗口创建

(1)glfw初始化

    glfwInit();  //初始化GLFW库 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);    //指定了OpenGL上下文的版本为3.3。
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);    //指定了OpenGL的核心(profile)模式,这意味着只能使用现代的OpenGL功能,而不是旧版功能。

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);    //苹果操作系统(macOS)上设置OpenGL的前向兼容性模式
#endif

(2)创建窗口

glfwCreateWindow 是 GLFW 库中用于创建窗口的函数。参数和功能如下:

①SCR_WIDTHSCR_HEIGHT: 这两个参数分别表示所创建窗口的宽度和高度。

②"LearnOpenGL": 这是窗口的标题,将显示在窗口的标题栏上。

③NULLNULL: 这两个参数分别表示要将窗口与另一个窗口共享上下文和帧缓冲,通常情况下我们不需要这样做,所以将它们设置为 NULL。

然后判断窗口创建是否成功,如果创建失败则打印报错,同时调用glfwTerminate()函数,用于释放 GLFW 库所分配的所有资源并终止 GLFW 库的运行。写到这一步调试时已经可以看见窗口,但会立刻退出关闭。

    //创建窗口,五个参数分别为:窗口的宽度、高度、窗口标题、窗口模式(默认窗口、全屏窗口、窗口)、共享上下文(默认不共享)
    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;
    }

(3)初始化GLAD

给GLAD传入用来加载系统相关的OpenGL函数指针地址的函数。

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

(4)窗口输入函数定义(可选)

①esc退出函数

这是 glfwGetKey() 函数的调用,它用于检查特定窗口中某个键是否被按下。第一个参数 window 是你要检查的窗口的指针,第二个参数 GLFW_KEY_ESCAPE 是指定要检查的键,这里是esc 键。

void processInput(GLFWwindow* window)   //处理输入
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)   //当按下ESC键时,关闭窗口
        glfwSetWindowShouldClose(window, true);
}

②窗口回调函数

我们需要告诉OpenGL渲染窗口的尺寸大小,即视口(Viewport),这样OpenGL才只能知道怎样根据窗口大小显示数据和坐标。我们可以通过调用glViewport函数来设置窗口的纬度(Dimension)

void framebuffer_size_callback(GLFWwindow* window, int width, int height)  {   //通常需要调整视口(Viewport)的大小

    glViewport(0, 0, width, height);   //视口设置函数,别是视口的左下角坐标(通常为(0, 0)),以及视口的宽度和高度。
}

(5)循环窗口

这里需要注意 glfwSwapBuffers(window); 函数不能遗漏。

glfwSwapBuffers函数是GLFW库中的一个函数,用于交换前后缓冲区的内容,以显示最新的渲染结果。在 GLFW 中,默认情况下是使用双缓冲来避免闪烁和提供更平滑的图形渲染效果(也可以通过glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE);函数修改为单缓冲模式)。

双缓冲模式下,当我们使用图形库(如OpenGL)绘制场景时,所有的绘制操作都是在后台缓冲区进行的,而用户实际看到的图像则是前台缓冲区的内容。当一帧图像渲染完成后,通过交换缓冲区的操作,将后台缓冲区的内容交换到前台缓冲区,从而实现了平滑的图像显示,避免了闪烁和图像不完整的情况。

    while (!glfwWindowShouldClose(window))  //这是一个GLFW函数,用于检查窗口是否应该关闭。当用户关闭窗口时,这个函数返回true,否则返回false。
    {
        processInput(window); //用于处理输入

        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);  //函数设置清除颜色,即在每次渲染循环开始时,OpenGL会用这个颜色来清除屏幕
        glClear(GL_COLOR_BUFFER_BIT);  //清除颜色缓冲区,以清除之前渲染的内容,以便进行新的渲染

        glfwSwapBuffers(window);    //交换缓冲区,将渲染结果显示到屏幕上
        glfwPollEvents();  //这个函数用于处理窗口事件,比如键盘输入、鼠标移动等。

        
    }

3、完整代码

完整代码如下:

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>

using namespace std;

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);

// 设置窗口大小
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

int main()
{
    glfwInit();  //初始化GLFW库 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);    //指定了OpenGL上下文的版本为3.3。
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);    //指定了OpenGL的核心(profile)模式,这意味着只能使用现代的OpenGL功能,而不是旧版功能。

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);    //苹果操作系统(macOS)上设置OpenGL的前向兼容性模式
#endif

    //创建窗口,五个参数分别为:窗口的宽度、高度、窗口标题、窗口模式(默认窗口、全屏窗口、窗口)、共享上下文(默认不共享)
    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
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    while (!glfwWindowShouldClose(window))  //这是一个GLFW函数,用于检查窗口是否应该关闭。当用户关闭窗口时,这个函数返回true,否则返回false。
    {
        processInput(window); //用于处理输入

        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);  //函数设置清除颜色,即在每次渲染循环开始时,OpenGL会用这个颜色来清除屏幕
        glClear(GL_COLOR_BUFFER_BIT);  //清除颜色缓冲区,以清除之前渲染的内容,以便进行新的渲染

        glfwSwapBuffers(window);    //交换缓冲区,将渲染结果显示到屏幕上
        glfwPollEvents();  //这个函数用于处理窗口事件,比如键盘输入、鼠标移动等。

        //当我们使用图形库(如OpenGL)绘制场景时,所有的绘制操作都是在后台缓冲区进行的,而用户实际看到的图像则是前台缓冲区的内容。当一帧图像渲染完成后,通过交换缓冲区的操作,将后台缓冲区的内容交换到前台缓冲区,从而实现了平滑的图像显示,避免了闪烁和图像不完整的情况。
    }

    glfwTerminate();   //用于释放 GLFW 库所分配的所有资源并终止 GLFW 库的运行
    return 0;
}

void processInput(GLFWwindow* window)   //处理输入
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)   //当按下ESC键时,关闭窗口
        glfwSetWindowShouldClose(window, true);
}


void framebuffer_size_callback(GLFWwindow* window, int width, int height)  {   //窗口大小变化回调函数

    glViewport(0, 0, width, height);   //视口设置函数,别是视口的左下角坐标(通常为(0, 0)),以及视口的宽度和高度。
}

运行结果如下,会显示一个绿色背景的窗口:

NEHE的OPENGL教程 第42课 多视窗口… NEHE的OPENGL教程 第42课 多视窗口… NeHe的OPENGL中文教程:第41课 体… NeHe的OPENGL中文教程:第40课 绳… NeHe的OPENGL中文教程:第39课 物… NeHe的OPENGL中文教程:第39课 物… NeHe的OPENGL中文教程:第38课 从… NeHe的OPENGL中文教程:第37课 卡… 愚人节十大IT假新闻:Opera浏览器… NeHe的OPENGL中文教程:第36课 放… NeHe的OPENGL中文教程:第35课 AVI… NeHe的OPENGL中文教程:第35课 AVI… NeHe的OPENGL中文教程:第34课 从… NeHe的OPENGL中文教程:第33课 加… NeHe的OPENGL中文教程:第32课 Alp… NeHe的OPENGL中文教程:第32课 Alp… NeHe的OPENGL中文教程:第32课 Alp… NeHe的OPENGL中文教程:第31课 模… NEHE的OPENGL中文教程:第30课 碰… NEHE的OPENGL中文教程:第30课 碰… NeHe的OPENGL中文教程:第29课 Bli… NeHe的OPENGL中文教程:第28课 贝… NeHe的OPENGL中文教程:第27课 影… NeHe的OPENGL中文教程:第26课剪裁… NeHe的OPENGL中文教程:第25课 变… NeHe的OPENGL中文教程:第24课 TAG… NeHe的OPENGL中文教程:第23课 球… NeHe的OPENGL中文教程:第22课 凸… NeHe的OPENGL中文教程:第22课 凸… NeHe的OPENGL中文教程:第21课 反… NeHe的OPENGL中文教程:第21课 反… NeHe的OPENGL中文教程:第20课 蒙… NeHe的OPENGL中文教程:第19课 粒… NeHe的OPENGL中文教程:第18课 … NeHe的OPENGL中文教程:第17课 2D… NeHe的OPENGL中文教程:第16课 雾 NeHe的OPENGL中文教程:第15课 图… NeHe的OPENGL中文教程:第14课 图… NeHe的OPENGL中文教程:第13课 位… NeHe的OPENGL中文教程:第12课 显… NeHe的OPENGL中文教程:第11课 飘… NeHe的OPENGL中文教程:第十课 漫… NeHe的OPENGL中文教程:第九课 漂… NeHe的OPENGL中文教程:第八课 Alp… NeHe的OPENGL中文教程:第七课 纹… NeHe的OPENGL中文教程:第七课 纹… NeHe的OPENGL中文教程:第六课 纹… NeHe的OPENGL中文教程:第五课 向3… NeHe的OPENGL中文教程:第四课 旋… NeHe的OPENGL中文教程:第三课 着… NeHe的OPENGL中文教程:第课 多… NeHe的OPENGL中文教程:第一课 新… NeHe的OPENGL中文教程:第一课 新… DirectX与OpenGL方面的经典电子书… VC++ 6.0下OpengGL配置以及glut配… 怎样开始学习OpenGL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值