直接上代码,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