#include "glfw.hpp" // #include "renderer/renderer.hpp" // #include "event/system_event/category/key_event.hpp" // #include "event/system_event/category/window_event.hpp" namespace VE { glfw::glfw() { if (!glfwInit()) { hack::error()("Not glfw window init"); std::terminate(); } } glfw::~glfw() { hack::warn(": ")("Destroy glfw window", m_win_data.m_name); glfwDestroyWindow(m_win); glfwTerminate(); } void glfw::init(std::string win_name) { m_win_data.m_name = win_name; set_hint(); set_window(); set_graphic_context(); set_pointer(); set_key_callback(); set_mouse_callback(); set_window_callback(); set_opengl(); } void glfw::set_hint() { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_SAMPLES, 4); hack::log()("Set glfw window hint"); } void glfw::set_window() { // два полследних nullptr // первый - устанавливает монитор на ктором будетоткрытие(основной, дополнительнй) // второй - делиться ли ресурсами с кем-то m_win = glfwCreateWindow( glfwGetVideoMode(glfwGetPrimaryMonitor())->width, glfwGetVideoMode(glfwGetPrimaryMonitor())->height, m_win_data.m_name.c_str(), nullptr, nullptr ); if(m_win == NULL) { hack::error()("Failed to create GLFW window"); glfwTerminate(); std::terminate(); } glfwGetWindowSize(m_win, &m_win_data.m_width, &m_win_data.m_height); hack::log(": ")("Created glfw window", m_win_data.m_name); hack::log(" = ")(" width", m_win_data.m_width); hack::log(" = ")(" height", m_win_data.m_height); } void glfw::set_graphic_context() { m_context = std::make_unique(m_win); hack::log()("Set context"); } void glfw::set_pointer() { glfwSetWindowUserPointer(m_win, &m_win_data); } GLFWwindow* glfw::get_win() const { return m_win; } int glfw::width() const { return m_win_data.m_width; } int glfw::height() const { return m_win_data.m_height; } void glfw::update() { glfwPollEvents(); m_context->swap_buffers(); } void glfw::clear() const { glClearColor(m_bgcolor.r, m_bgcolor.g, m_bgcolor.b, m_bgcolor.a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void glfw::set_event_fn(const event_fn& fn) { m_win_data.execute = fn; } void glfw::set_key_callback() { glfwSetKeyCallback(m_win, [](GLFWwindow* w, int key, int scancode, int action, int mods) { auto d = static_cast(glfwGetWindowUserPointer(w)); event e{ action, key }; // HERE // тут одноврекменно срабатывает только один сигнал // т.е. если нажада клавиша и удерживается сигнал о повторе идет // но если нажать одновременно еще, то сигнал о той нажатой пропадает // нужносамому реализовывать функцию повтора а не полагаться на внутреннюю // реализацию glfw switch (action) { case GLFW_PRESS: { e.m_type = event_type::KEY_PRESSED; break; } case GLFW_RELEASE: { e.m_type = event_type::KEY_RELEASED; break; } case GLFW_REPEAT: { e.m_type = event_type::KEY_REPEATE; break; } } d->execute(e); }); } void glfw::set_mouse_callback() { glfwSetMouseButtonCallback(m_win, [](GLFWwindow* w, int button, int action, int mods) { auto d = static_cast(glfwGetWindowUserPointer(w)); event e{ action, button }; switch (action) { case GLFW_PRESS: { e.m_type = event_type::MOUSE_BUTTON_PRESSED; break; } case GLFW_RELEASE: { e.m_type = event_type::MOUSE_BUTTON_RELEASED; break; } } d->execute(e); }); glfwSetScrollCallback(m_win, [](GLFWwindow* w, double xOffset, double yOffset) { auto d = static_cast(glfwGetWindowUserPointer(w)); event e{ event_type::MOUSE_SCROLL, std::pair{ static_cast(xOffset), static_cast(yOffset) } }; d->execute(e); }); glfwSetCursorPosCallback(m_win, [](GLFWwindow* w, double xPos, double yPos) { auto d = static_cast(glfwGetWindowUserPointer(w)); event e{ event_type::MOUSE_CURSOR_POSITION, std::pair{ static_cast(xPos), static_cast(yPos) } }; d->execute(e); }); } void glfw::set_window_callback() { glfwSetWindowSizeLimits(m_win, m_win_data.m_width, m_win_data.m_height, GLFW_DONT_CARE, GLFW_DONT_CARE); glfwSetWindowSizeCallback(m_win, [](GLFWwindow* w, int width, int height) { auto d = static_cast(glfwGetWindowUserPointer(w)); d->m_width = width; d->m_height = height; event e{ event_type::WINDOW_RESIZE, std::pair{ static_cast(width), static_cast(height) } }; d->execute(e); }); glfwSetWindowCloseCallback(m_win, [](GLFWwindow* w) { auto d = static_cast(glfwGetWindowUserPointer(w)); event e{ event_type::WINDOW_CLOSE, nullptr }; d->execute(e); }); glfwSetWindowFocusCallback(m_win, [](GLFWwindow* w, int focused) { auto d = static_cast(glfwGetWindowUserPointer(w)); event e{ event_type::WINDOW_FOCUS, focused }; d->execute(e); }); } void glfw::set_opengl() { glEnable(GL_DEPTH_TEST); glClearColor(0.07f, 0.13f, 0.17f, 1.0f); glViewport(0, 0, m_win_data.m_width, m_win_data.m_height); } }