直接上代码,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(); }
程序执行结果截图:
sdragonx https://github.com/sdragonx