直接上代码,glfw_window.hpp:

#ifndef GLFW_WINDOW_HPP
#define GLFW_WINDOW_HPP

#include <cstdlib>                          // onexit()

#pragma execution_character_set("utf-8")    // utf8 中文支持
#include <glfw/glfw3.h>


class glfw_window
{
public:
    GLFWwindow* window;

public:
    glfw_window() : window()
    {
        
    }

    glfw_window(const char* title, int width, int height) : window()
    {
        this->init(title, width, height);
    }

    //
    // 方法
    //

    // 创建 glfw 窗口
    int init(const char* title, int width, int height)
    {
        glfw_init();

        window = glfwCreateWindow(width, height, title, nullptr, nullptr);

        if (!window) {
            // err...
            return -1;
        }

        // 设置当前窗口上下文
        glfwMakeContextCurrent(window);

        // 设置用户数据,记录当前类指针
        glfwSetWindowUserPointer(window, this);

        // 原始 glfw 事件回调函数设置
        glfwSetKeyCallback(window, on_key);
        glfwSetCharCallback(window, on_char);
        glfwSetMouseButtonCallback(window, on_mouse_button);
        glfwSetCursorPosCallback(window, on_cursor_pos);

        return 0;
    }

    // 释放窗口
    void dispose()
    {
        if (window) {
            // 执行释放事件
            this->on_dispose();

            // 销毁窗口
            glfwDestroyWindow(window);
            window = nullptr;
        }
    }

    // 执行
    int run()
    {
        // 执行 on_init() 事件。虚函数在构造函数里面不执行,只能放这。
        this->on_init();

        while (!glfwWindowShouldClose(window)) {

            this->on_draw();            // 绘制函数调用

            glfwSwapBuffers(window);    // 反转缓冲区
            glfwPollEvents();           // 窗口事件处理
        }

        // 调用释放函数
        this->dispose();

        return 0;
    }

    // 退出
    void quit()
    {
        if (window) {
            glfwSetWindowShouldClose(window, GLFW_TRUE);
        }
    }

    //
    // 属性
    //

    // 设置标题
    void set_title(const char* title)
    {
        glfwSetWindowTitle(window, title);
    }

    // 设置窗口范围
    void set_bounds(int x, int y, int width, int height)
    {
        glfwSetWindowPos(window, x, y);
        glfwSetWindowSize(window, width, height);
    }

    // 窗口左边位置
    int left()const
    {
        int n;
        glfwGetWindowPos(window, &n, NULL);
        return n;
    }

    // 窗口右边位置
    int top()const
    {
        int n;
        glfwGetWindowPos(window, NULL, &n);
        return n;
    }

    // 窗口宽度
    int width()const
    {
        int n;
        glfwGetWindowSize(window, &n, NULL);
        return n;
    }

    // 窗口高度
    int height()const
    {
        int n;
        glfwGetWindowSize(window, NULL, &n);
        return n;
    }

    // ... 其他实现

    //
    // 事件,通过重载实现调用
    //

    virtual void on_init()
    {

    }

    virtual void on_dispose()
    {

    }

    virtual void on_keydown(int key)
    {

    }

    virtual void on_keyup(int key)
    {

    }

    virtual void on_char(uint32_t ch)
    {

    }

    // 绘制事件
    virtual void on_draw()
    {

    }

    // ... 其他实现

private:// glfw回调函数

    // 获取 glfw 窗口的用户数据,转换成 glfw_window 类指针。
    static glfw_window* get_window(GLFWwindow* window)
    {
        void* userdata = glfwGetWindowUserPointer(window);
        return reinterpret_cast<glfw_window*>(userdata);
    }

    //
    // 静态函数,由 glfw 直接调用
    //

    static void on_key(GLFWwindow* window, int key, int scancode, int action, int modifier)
    {
        glfw_window* winobj = get_window(window);

        switch (action) {
        case GLFW_RELEASE:
            winobj->on_keydown(key);
            break;
        case GLFW_PRESS:
            winobj->on_keyup(key);
            break;
        }
    }

    static void on_char(GLFWwindow* window, unsigned int ch)
    {
        glfw_window* winobj = get_window(window);
        winobj->on_char(ch);
    }

    // 其他实现...

    static void on_mouse_button(GLFWwindow* window, int button, int action, int mods)
    {

    }

    static void on_cursor_pos(GLFWwindow* window, double xpos, double ypos)
    {

    }

private:// 自动初始化
    static void glfw_init()
    {
        // 标记是否初始化,这个根据需要调整实现,可以用 singleton。
        static bool init = false;

        if (!init) {
            init = true;

            glfwInit();
            onexit(glfw_dispose);   // 程序退出时自动执行销毁函数
        }
    }

    static int __cdecl glfw_dispose()
    {
        glfwTerminate();
        return 0;
    }
};

#endif// GLFW_WINDOW_HPP

  

测试代码,main.cpp

#include "glfw_window.hpp"

class MyApp : public glfw_window
{
public:
    MyApp() : glfw_window() {}

    MyApp(const char* title, int width, int height) : glfw_window(title, width, height)
    {
    }

    void on_init()override
    {
        this->set_title("Yes OpenGL!");
    }

    void on_draw()override
    {
        glClearColor(0.0f, 0.5f, 1.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        //...
    }

};


int main(int argc, char* argv[])
{
    MyApp app = MyApp("OpenGL", 800, 600);

    return app.run();
}

  

程序执行结果截图: