OpenGL学习笔记【4】——创建窗口

   一、前三章节的前情回顾

章节一:上下文(Context)

   OpenGL学习笔记【1】——简介-CSDN博客

      章节一讲述了OpenGL在渲染的时候需要一个Context来记录了OpenGL渲染需要的所有信息和状态,可以把上下文理解成一个大的结构体,它里面记录了当前绘制使用的颜色、是否有光照计算以及开启的光源等。不同的操作系统,都有各自的上下文创建方法,最简单的上下文可以通过GLFW创建。

章节二:GLFW库

OpenGL学习笔记【2】——开发环境配置(GLFW,VS,Cmake),创建第一个项目-CSDN博客

       章节二讲述了一个专门的窗口库:GLFW库,一个轻量级的图形界面框架,GLFW 的主要功能创建并管理窗口和 OpenGL 上下文,同时还提供了处理手柄、键盘、鼠标输入的功能。

      章节二还创建了一个空项目MyFirstOpenGL。

章节三: GLAD库

  OpenGL学习笔记【3】—— GLAD配置-CSDN博客

     章节三讲述了GLAD库是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要初始化GLAD,从而让我们能够使用所有OpenGL函数。

    章节三还创建了一个main.cpp文件,代码中引入了GLAD和GLFW的两个库文件。

前三章节准备工作已经完成,接下来可以开始创建窗口了

二、创建窗口步骤

  2.1、初始化GLFW库

   glfwInit()函数:  一般我们使用Glfw库,首先初始化GLFW库,即需要调用glfwInit()得到OpenGL随显卡驱动一起发布的新特性的函数入口地址。

  2.2、 glfwWindowHint配置GLFW

     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)

       使用核心模式(Core-profile),在调用一个OpenGL的废弃函数时会产生invalid operation 错误,当意外的使用了不该使用的旧函数时是一个很好的提醒。

    注意:请确认您的系统支持OpenGL3.3或更高版本,否则此应用有可能会崩溃或者出现不可预知的错误,如果你的OpenGL版本低于3.3,检查一下显卡是否支持OpenGL 3.3+(不支持的话你的显卡真的太老了),并更新你的驱动程序,有必要的话请更新显卡。

  2.3、创建一个窗口对象

(1) glfwCreateWindow()函数:创建窗口对象 返回值类型GLFWwindow*

参数1,2为窗口的宽度和高度,参数3是窗口的名字,最后两个参数可以忽略。

glfwCreateWindow 创建了一个宽度为800像素、高度为600像素的窗口。

  注意: 其实处理过的的窗口值是从-1到1的显示,而(0,0)点就是窗口的中心。

(2) glfwMakeContextCurrent(window)函数:

将窗口window设置为当前线程的主上下文,即捕获当前窗口,准备对当前窗口进行画图.

 (3) glfwTerminate(); 终止GLFW,释放资源。

2.4、渲染循环

      为了在主动关闭GLFW之前可以不断绘制,在OpenGL中需要添加一个while循环,我们可以把它称之为渲染循环(Render Loop)。如果没有渲染循环,程序运行的话渲染效果只会出现一次就会快速消失。

 glfwWindowShouldClose(window)函数:检查GLFW是否被要求退出。

2.5、点击本地Windows调试器运行测试

运行结果如下就表示窗口创建成功了

三、窗口创建后,在窗口里面需创建一个“视口”

    在我们开始渲染之前还有一件重要的事情要做,我们必须告诉OpenGL渲染窗口(即视口)的尺寸大小,即需要创建一个视口。  

  3.1、创建视口之前,需要先初始化GLAD

       因为用来创建视口的函数glViewport()是openGL的函数,由第三章节对于GLAD的介绍我们已经知道在调用任何OpenGL的函数之前需要先初始化GLAD,初始化后我们才能够使用所有的OpenGL函数。

//初始化GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
    //初始化失败,即加载函数地址失败,打印错误信息
    std::cout << "Failed to initialize GLAD" << std::endl;
    return -1;
}

    gladLoadGLLoader(GLADloadproc)函数:根据我们编译的系统,GLAD库中用于加载系统相关的OpenGL函数指针地址。参数1为GLADloadproc类型的函数指针地址。这里我们通过GLFW中的glfwGetProcAddress属性获取了函数指针的的地址。

    初始化GLAD后,接下来就能够使用所有OpenGL函数 了,即可以创建视口.

    3.2、创建视口(glViewport)

 //参数1,2:渲染窗口左下角的位置
 //参数3,4:渲染窗口的宽度和高度(单位:像素)
 glViewport(0, 0, 800, 600);

  让我捋一下哈,刚才还在创建窗口,现在又有一个渲染窗口(视口),是不是有一丢丢儿蒙圈,其实不难理解:glfwCreateWindow 和 glViewport 是两个不同的函数。glfwCreateWindow 是GLFW库中的函数,用于创建一个OpenGL窗口。而glViewport 是OpenGL的函数,用于设置渲染窗口的大小和位置 。

     这里存在两个分辨率,其中glfwCreateWindow是实际的窗口大小分辨率,glViewport是OpenGL视口的分辨率,这两个分辨率是可以不一致的,不一致的后果就是OpenGl会绘制部分内容在你的实际窗口外,或者内部。

四、释放/删除之前分配的所有资源

  //终止GLFW,释放所有资源====================
    glfwTerminate();

   此章节的代码如下所示:

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>// C++的标准输入输出头文件
int main() 
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//设置主板本号为3
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//设置副版本号为3
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    //创建窗口对象 返回值类型:GLFWwindow*
    GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
    if (window == NULL)//创建窗口对象失败,打印错误信息
    {    
        std::cout << "Failed to create GLFW window" << std::endl;//需要引用iostream头文件      
        glfwTerminate(); //终止GLFW
        return -1;
    }  
    glfwMakeContextCurrent(window); //将窗口的上下文设置为当前线程的主上下文
    //渲染循环
    while (!glfwWindowShouldClose(window))
    {    
        
    }
    //初始化GLAD
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        //初始化失败,即加载函数地址失败,打印错误信息
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }
    //参数1,2:渲染窗口左下角的位置
    //参数3,4:渲染窗口的宽度和高度(单位:像素)
    glViewport(0, 0, 800, 600);
    //终止GLFW,释放所有资源====================
    glfwTerminate();

	return 0;
}

 下一章节:OpenGL学习笔记【5】——给窗口添加渲染颜色以及监听键盘输入

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-03-22 11:34:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-22 11:34:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-22 11:34:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-22 11:34:01       18 阅读

热门阅读

  1. pyqt5与selenium混合使用心得

    2024-03-22 11:34:01       17 阅读
  2. 【HTML面试题】src和href的区别

    2024-03-22 11:34:01       18 阅读
  3. Jenkins Pipeline 流水线

    2024-03-22 11:34:01       18 阅读
  4. .net Core 微服务接口增加过滤器实现预处理

    2024-03-22 11:34:01       18 阅读
  5. ARM作业

    ARM作业

    2024-03-22 11:34:01      15 阅读
  6. 常用GPT网站综述:探索人工智能的前沿技术平台

    2024-03-22 11:34:01       14 阅读
  7. AI新纪元:Sora、GPT-5及未来技术的前沿探索

    2024-03-22 11:34:01       18 阅读
  8. ARMday6

    2024-03-22 11:34:01       14 阅读
  9. 微信小程序处理ArrayBuffer拼接问题

    2024-03-22 11:34:01       16 阅读
  10. C语言——指针练习:输出最大值与最小值

    2024-03-22 11:34:01       16 阅读
  11. 串口与中断的关系和使用--详细解释

    2024-03-22 11:34:01       19 阅读
  12. Android中广播的基本介绍

    2024-03-22 11:34:01       22 阅读
  13. STM32利用ADC和DMA外设读取4路电压值Oled显示

    2024-03-22 11:34:01       19 阅读