1.1 HELLO 窗口

发布时间 2023-07-25 14:11:58作者: 跳岩

跟着教程,开始第一步创建窗口吧!这一节不涉及太多知识。
本节会出现一些名词,我们现在只需要知道它们大概是干什么的就行。
● GLFW:一个专门针对OpenGL的C语言库,通过它提供的接口,我们就可以渲染物体了;
● GLAD:用来管理OpenGL函数指针的库,在调用所有OpenGL函数之前,我们要初始GLAD;
● 视口(Viewport):渲染窗口是我们渲染物体的地方,就像一个“画布”,而视口就是这个“画布”的尺寸。在开始渲染(“画”)物体之前,总要规定视口(“画布”)大小的,对吧?

一个比较完整的流程(的伪代码)就像是这样:

#include <各种你需要的库>

int main(){
    // 初始化GLFW, 实例化GLFW窗口, 设置一些窗口对象的基本属性
    // ..........

    // 还记得吗,在调用所有OpenGL函数之前,我们要初始GLAD
    // ..........

    // 渲染之前,还要设置视口
    // ..........

    // 准备工作做完了!开始渲染循环(Rending Loop)
    while (当前的window还没关闭){
        // 输入控制
        // ........

        // 各种各样的渲染的指令
        // ........

        // 检查并调用事件,交换缓冲(见双缓冲, Double Buffer)
        // ........
    }
    
    // 渲染完了,释放已经不需要的资源
    // ..........

    return 0;
}

嗯……很成功!这是源代码:

/*
Hello 窗口=v=
*/
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <bits/stdc++.h>
using namespace std;

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

int main(void) {
    // 实例化GLFW窗口, 选项的详细含义可以参见 https://www.glfw.org/docs/latest/window.html#window_hints
    glfwInit();// 初始化GLFW
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // 创建窗口对象, 存放所有和窗口相关的数据
    GLFWwindow * window = glfwCreateWindow(800, 600, "startMagic...", NULL, NULL);
    if (NULL == window) {
        cout << "Failed to create GLFW window" << endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window); // 将窗口的上下文设置为当前线程的主上下文

    // GLAD是用来管理OpenGL的函数指针的, 所以在调用任何OpenGL的函数之前我们要初始化GLAD
    // 我们给GLAD传入了用来加载系统相关的OpenGL函数指针地址的函数
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        cout << "Failed to initialize GLAD" << endl;
        return -1;
    }
    // 设置渲染窗口的尺寸大小, 即视口(Viewport)
    glViewport(0, 0, 800, 600); // 窗口左下角位置, 渲染窗口的宽/高
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // 渲染循环(Render Loop), 能在我们让GLFW退出前一直保持运行
    while (!glfwWindowShouldClose(window)) {
        // 输入
        processInput(window);
        // 渲染指令
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // 状态设置函数
        glClear(GL_COLOR_BUFFER_BIT); // 状态使用函数
        // 检查并调用事件, 交换缓冲
        glfwSwapBuffers(window); // 交换颜色缓冲
        glfwPollEvents(); // 检查有没有触发什么事件, 并调用对应的回调函数
    }
    glfwTerminate();

    return 0;
}

// 回调函数(Callback Function)会在每次窗口大小被调整时被调用, 当窗口大小改变时同时改变视口大小
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);
    }
}

生成了一个蓝绿色窗口,并且按esc键可以退出。

下面开始hello三角形!