Tôi đã có một vấn đề tương tự như thế này. Thật khó chịu khi có quá ít tài liệu về việc sử dụng glfwSetWindowUserPulum và glfGetWindowUserPulum. Đây là giải pháp của tôi cho vấn đề của bạn:
WindowManager::WindowManager() {
// ...
glfwSetUserPointer(window_, this);
glfwSetKeyCallback(window_, key_callback_);
// ...
}
void WindowManager::key_callback(GLFWwindow *window, int, int ,int, int) {
WindowManager *windowManager =
static_cast<WindowManager*>(glfwGetUserPointer(window));
Keyboard *keyboard = windowManager->keyboard_;
switch(key) {
case GLFW_KEY_ESCAPE:
keyboard->reconfigure();
break;
}
}
Dù sao, vì đây là một trong những kết quả hàng đầu để sử dụng GLFW với các lớp C ++, tôi cũng sẽ cung cấp phương pháp đóng gói glfwWindow trong lớp C ++. Tôi nghĩ rằng đây là cách thức thanh lịch nhất để làm điều đó, vì nó tránh phải sử dụng toàn cầu, singletons hoặc unique_ptrs, cho phép lập trình viên điều khiển cửa sổ theo kiểu OO / C ++ - y hơn và cho phép phân lớp (với chi phí một tập tin tiêu đề lộn xộn hơn một chút).
// Window.hpp
#include <GLFW/glfw3.h>
class Window {
public:
Window();
auto ViewportDidResize(int w, int h) -> void;
// Make virtual you want to subclass so that windows have
// different contents. Another strategy is to split the
// rendering calls into a renderer class.
(virtual) auto RenderScene(void) -> void;
(virtual) auto UpdateScene(double ms) -> void;
// etc for input, quitting
private:
GLFWwindow *m_glfwWindow;
// Here are our callbacks. I like making them inline so they don't take up
// any of the cpp file
inline static auto WindowResizeCallback(
GLFWwindow *win,
int w,
int h) -> void {
Window *window = static_cast<Window*>(glfwGetUserPointer(win));
window->ViewportDidResize(w, h);
}
inline static auto WindowRefreshCallback(
void) -> void {
Window *window = static_cast<Window*>(glfwGetUserPointer(win));
window->RenderScene(void);
}
// same for input, quitting
}
Va cho:
// Window.cpp
#include <GLFW/glfw3.h>
#include "Window.hpp"
Window::Window() {
// initialise glfw and m_glfwWindow,
// create openGL context, initialise any other c++ resources
glfwInit();
m_glfwWindow = glfwCreateWindow(800, 600, "GL", NULL, NULL);
// needed for glfwGetUserPointer to work
glfwSetWindowUserPointer(m_glfwWindow, this);
// set our static functions as callbacks
glfwSetFramebufferSizeCallback(m_glfwWindow, WindowResizeCallback);
glfwSetWindowRefreshCallback(m_glfwWindow, WindowRefreshCallback);
}
// Standard window methods are called for each window
auto
Window::ViewportDidResize(int w, int h) -> void
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
}
Điều này có thể được tích hợp khá dễ dàng với lớp WindowManager / InputManager, nhưng tôi nghĩ việc mỗi cửa sổ tự quản lý sẽ dễ dàng hơn.