// // Created by atdunbg on 2026/9/20. // #include #include #include namespace Engine { void Window::FramebufferResizeCallback(GLFWwindow* window, int width, int height) { auto* self = static_cast(glfwGetWindowUserPointer(window)); self->m_FramebufferResized = true; if (self->m_EventCallback) { Event e; e.type = EventType::WindowResize; e.width = width; e.height = height; self->m_EventCallback(e); } } void Window::KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { auto* self = static_cast(glfwGetWindowUserPointer(window)); if (!self->m_EventCallback || key == GLFW_KEY_UNKNOWN) return; // UI 捕获键盘时,游戏侧不收键盘事件(ImGui 后端链式回调自行处理) if (self->m_KeyboardCapture && self->m_KeyboardCapture()) return; Event e; e.key = key; e.type = (action == GLFW_PRESS) ? EventType::KeyPress : (action == GLFW_RELEASE) ? EventType::KeyRelease : EventType::None; // GLFW_REPEAT 暂不透出 if (e.type != EventType::None) self->m_EventCallback(e); } void Window::MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) { auto* self = static_cast(glfwGetWindowUserPointer(window)); if (!self->m_EventCallback) return; if (self->m_MouseCapture && self->m_MouseCapture()) return; Event e; e.button = button; e.type = (action == GLFW_PRESS) ? EventType::MouseButtonPress : EventType::MouseButtonRelease; self->m_EventCallback(e); } void Window::CursorPosCallback(GLFWwindow* window, double xpos, double ypos) { auto* self = static_cast(glfwGetWindowUserPointer(window)); if (!self->m_EventCallback) return; if (self->m_MouseCapture && self->m_MouseCapture()) return; Event e; e.type = EventType::MouseMove; e.x = static_cast(xpos); e.y = static_cast(ypos); self->m_EventCallback(e); } void Window::ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) { auto* self = static_cast(glfwGetWindowUserPointer(window)); if (!self->m_EventCallback) return; if (self->m_MouseCapture && self->m_MouseCapture()) return; Event e; e.type = EventType::MouseScroll; e.deltaX = static_cast(xoffset); e.deltaY = static_cast(yoffset); self->m_EventCallback(e); } void Window::WindowFocusCallback(GLFWwindow* window, int focused) { auto* self = static_cast(glfwGetWindowUserPointer(window)); if (!self->m_EventCallback) return; Event e; e.type = focused ? EventType::WindowFocus : EventType::WindowLostFocus; self->m_EventCallback(e); } Window::Window(const std::string& title, u32 width, u32 height) : m_Width(width), m_Height(height), m_Title(title) { if (!glfwInit()) { ENGINE_FATAL("glfwInit failed"); return; } glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); // glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); m_Window = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr); if (!m_Window) { ENGINE_FATAL("glfwCreateWindow failed"); glfwTerminate(); return; } ENGINE_INFO("Window created: {} ({}x{})", title, width, height); // callbacks glfwSetWindowUserPointer(m_Window, this); glfwSetFramebufferSizeCallback(m_Window, FramebufferResizeCallback); glfwSetKeyCallback(m_Window, KeyCallback); glfwSetMouseButtonCallback(m_Window, MouseButtonCallback); glfwSetCursorPosCallback(m_Window, CursorPosCallback); glfwSetScrollCallback(m_Window, ScrollCallback); glfwSetWindowFocusCallback(m_Window, WindowFocusCallback); } Window::~Window() { if (m_Window) { glfwDestroyWindow(m_Window); } glfwTerminate(); } bool Window::ShouldClose() const { return glfwWindowShouldClose(m_Window); } void Window::PollEvents() { glfwPollEvents(); } vk::SurfaceKHR Window::CreateSurface(vk::Instance instance) { VkSurfaceKHR surface; if (glfwCreateWindowSurface(instance, m_Window, nullptr, &surface) != VK_SUCCESS) { ENGINE_FATAL("glfwCreateWindowSurface failed"); return nullptr; } return surface; } void Window::DestroySurface(vk::Instance instance, vk::SurfaceKHR surface) { instance.destroySurfaceKHR(surface); } std::vector Window::GetRequiredExtensions() { u32 count = 0; const char** extensions = glfwGetRequiredInstanceExtensions(&count); return std::vector(extensions, extensions + count); } void Window::GetFramebufferSize(int& width, int& height) const { glfwGetFramebufferSize(m_Window, &width, &height); } bool Window::IsKeyPressed(int key) const { // UI 捕获键盘时,轮询接口同样静默(相机等轮询型消费方) if (m_KeyboardCapture && m_KeyboardCapture()) return false; return glfwGetKey(m_Window, key) == GLFW_PRESS; } void Window::GetMouseDelta(float& dx, float& dy) { double mx, my; glfwGetCursorPos(m_Window, &mx, &my); static double lastX = mx; static double lastY = my; static bool first = true; if (first) { lastX = mx; lastY = my; first = false; dx = dy = 0.0f; return; } dx = static_cast(mx - lastX); dy = static_cast(my - lastY); lastX = mx; lastY = my; // UI 捕获鼠标时 delta 归零;lastX/Y 照常更新,避免释放后跳变 if (m_MouseCapture && m_MouseCapture()) { dx = dy = 0.0f; } } } // namespace Engine