三、创建窗口

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

using namespace std;

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

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);

    // glfw window creation
    GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        cout << "Filed to create GLFW window" << endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // glad: load all OpenGL function pointers
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        cout << "Filed to initialize GLAD" << 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();
    }

    glfwTerminate();
    return 0;
}
  1. 在包含GLFW的头文件之前先包含GLAD的头文件。GLAD的头文件包含了正确的OpenGL头文件(例如GL/gl.h),所以需要在其它依赖于OpenGL的头文件之前包含GLAD。
  2. glfwInit()用于初始化glfw库,在绝大多数glfw的函数使用前,都要先初始化glfw库,但是在程序结束前,必须要终止glfw(如果你运行之后vs卡死,很可能是忘了终止glfw),目的是为了释放资源,glfwTerminate会销毁窗口释放资源,因此在调用该函数后,如果想使用glfw库函数,就必须重新初始化。
  3. glfwSetErrorCallback(error_callback)可以在glfwInit()之前调用,错误回调由生成错误的线程调用。如果从多个线程使用GLFW,则需要相应地编写错误回调。
  4. GLFW_OPENGL_CORE_PROFILE表示非兼容,我的理解是不兼容以前的deprecated函数的调用。参考https://blog.csdn.net/csxiaoshui/article/details/79032464
  5. GLFW需要定期与窗口通信,以便接收事件。 事件处理必须在有可见窗口的情况下进行,并且通常在缓冲区交换后每帧执行一次。有两种方法用于处理挂起的事件:轮询glfwPollEvents()和等待glfwWaitEvent()。当你制作游戏或是动画时,尽量使用轮询。 如果相反,你需要在产生事件后才渲染,可是通过等待来处理事件,比如制作编辑器的时候,使用等待可以节省大量硬件资源。
  6. 应用程序使用单缓冲绘图时可能会存在图像闪烁的问题。 这是因为生成的图像不是一下子被绘制出来的,而是按照从左到右,由上而下逐像素地绘制而成的。最终图像不是在瞬间显示给用户,而是通过一步一步生成的,这会导致渲染的结果很不真实。为了规避这些问题,我们应用双缓冲渲染窗口应用程序。前缓冲保存着最终输出的图像,它会在屏幕上显示;而所有的的渲染指令都会在后缓冲上绘制。当所有的渲染指令执行完毕后,我们交换(Swap)前缓冲和后缓冲,这样图像就立即呈显出来,之前提到的不真实感就消除了。
  7. 参考:
    https://blog.csdn.net/meltlao2/article/details/80854788
    https://learnopengl-cn.github.io/01%20Getting%20started/03%20Hello%20Window/
    https://www.glfw.org/docs/3.0/group__error.html
    https://www.glfw.org/docs/latest/window.html#window_hints
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。