GLFW 的事件机制基于回调函数(Callback Functions) 和事件轮询(Event Polling) 实现,其核心设计围绕“事件驱动”模型。
核心机制
回调函数 Callbacks
GLFW 允许用户注册自定义函数(回调函数),当特定事件发生时(如键盘输入、鼠标点击、窗口大小变化等),GLFW 会自动调用这些函数。
示例:设置键盘回调
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GLFW_TRUE); // 按 ESC 关闭窗口
}
// 注册回调
glfwSetKeyCallback(window, key_callback);事件队列与轮询
- 所有输入事件(键盘、鼠标等)首先被存入 GLFW 的内部事件队列。
- 用户需在每帧调用
glfwPollEvents()或glfwWaitEvents()清空队列,触发回调函数执行:glfwPollEvents():立即处理所有挂起的事件(适合实时渲染)。glfwWaitEvents():阻塞线程直到新事件到达(适合非实时应用)。
while (!glfwWindowShouldClose(window)) {
glfwPollEvents(); // 处理事件(触发回调)
renderGraphics(); // 渲染逻辑
glfwSwapBuffers(window);
}状态查询 State Queries
除回调外,GLFW 提供即时状态查询函数(如 glfwGetKey()),可在主循环中直接检测输入状态:
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
// 空格键被按下
}主要事件类型与回调
| 事件类型 | 回调函数 | 说明 |
|---|---|---|
| 键盘按键 | glfwSetKeyCallback() |
处理键按下/释放/重复 |
| 鼠标移动 | glfwSetCursorPosCallback() |
光标位置变化 |
| 鼠标按钮 | glfwSetMouseButtonCallback() |
鼠标按键按下/释放 |
| 鼠标滚轮 | glfwSetScrollCallback() |
滚轮滚动 |
| 窗口大小改变 | glfwSetWindowSizeCallback() |
窗口尺寸变化 |
| 窗口关闭请求 | glfwSetWindowCloseCallback() |
点击关闭按钮时触发 |
| 文件拖拽到窗口 | glfwSetDropCallback() |
获取拖拽文件路径 |
| 显示器连接/断开 | glfwSetMonitorCallback() |
外接显示器变化 |
| 游戏手柄连接 | glfwSetJoystickCallback() |
手柄接入/断开 |
特点
-
线程安全性
回调函数在调用glfwPollEvents()的线程中执行(通常是主线程),需避免在回调中调用非线程安全的 GL 函数。 -
多窗口支持
每个GLFWwindow对象可独立设置回调函数,互不影响。 -
事件屏蔽
可通过glfwSetInputMode()禁用事件(如隐藏光标、锁定按键重复):CglfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // 隐藏鼠标光标