253 lines
6.3 KiB
C++
Executable File
253 lines
6.3 KiB
C++
Executable File
#include "glfw.hpp"
|
||
|
||
#include "event/type.hpp"
|
||
#include "event/api.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<context>(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_key_callback()
|
||
{
|
||
glfwSetKeyCallback(m_win, [](GLFWwindow* w, int key, int scancode, int action, int mods)
|
||
{
|
||
// HERE
|
||
// тут одноврекменно срабатывает только один сигнал
|
||
// т.е. если нажада клавиша и удерживается сигнал о повторе идет
|
||
// но если нажать одновременно еще, то сигнал о той нажатой пропадает
|
||
// нужносамому реализовывать функцию повтора а не полагаться на внутреннюю
|
||
// реализацию glfw
|
||
switch (action)
|
||
{
|
||
case GLFW_PRESS:
|
||
{
|
||
VE::EMIT(event_type::KEY_PRESSED, key);
|
||
break;
|
||
}
|
||
case GLFW_RELEASE:
|
||
{
|
||
VE::EMIT(event_type::KEY_RELEASED, key);
|
||
break;
|
||
}
|
||
case GLFW_REPEAT:
|
||
{
|
||
VE::EMIT(event_type::KEY_REPEATE, key);
|
||
break;
|
||
}
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
void glfw::set_mouse_callback()
|
||
{
|
||
glfwSetMouseButtonCallback(m_win, [](GLFWwindow* w, int button, int action, int mods)
|
||
{
|
||
switch (action)
|
||
{
|
||
case GLFW_PRESS:
|
||
{
|
||
static auto time = std::chrono::high_resolution_clock::now();
|
||
auto local = std::chrono::high_resolution_clock::now();
|
||
std::chrono::duration<double, std::milli> duration = local - time;
|
||
|
||
if (duration.count() > 10 && duration.count() < 200)
|
||
VE::EMIT(event_type::MOUSE_BUTTON_DOUBLE_PRESSED, button);
|
||
else
|
||
VE::EMIT(event_type::MOUSE_BUTTON_PRESSED, button);
|
||
|
||
time = local;
|
||
break;
|
||
}
|
||
case GLFW_RELEASE:
|
||
{
|
||
VE::EMIT(event_type::MOUSE_BUTTON_RELEASED, button);
|
||
break;
|
||
}
|
||
}
|
||
});
|
||
|
||
glfwSetScrollCallback(m_win, [](GLFWwindow* w, double xOffset, double yOffset)
|
||
{
|
||
try
|
||
{
|
||
auto data = std::pair<float, float>{ static_cast<float>(xOffset), static_cast<float>(yOffset) };
|
||
VE::EMIT(event_type::MOUSE_SCROLL, data);
|
||
}
|
||
catch(std::exception& e)
|
||
{
|
||
hack::log()("VE_ERROR: ", e.what());
|
||
}
|
||
});
|
||
|
||
glfwSetCursorPosCallback(m_win, [](GLFWwindow* w, double xPos, double yPos)
|
||
{
|
||
try
|
||
{
|
||
auto data = std::pair<float, float>{ static_cast<float>(xPos), static_cast<float>(yPos) };
|
||
VE::EMIT(event_type::MOUSE_CURSOR_POSITION, data);
|
||
}
|
||
catch(std::exception& e)
|
||
{
|
||
hack::log()("VE_ERROR: ", e.what());
|
||
}
|
||
});
|
||
}
|
||
|
||
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<win_data*>(glfwGetWindowUserPointer(w));
|
||
d->m_width = width;
|
||
d->m_height = height;
|
||
|
||
try
|
||
{
|
||
auto data = std::pair<float, float>{ static_cast<float>(width), static_cast<float>(height) };
|
||
VE::EMIT(event_type::WINDOW_RESIZE, data);
|
||
}
|
||
catch(std::exception& e)
|
||
{
|
||
hack::log()("VE_ERROR: ", e.what());
|
||
}
|
||
});
|
||
|
||
glfwSetWindowCloseCallback(m_win, [](GLFWwindow* w)
|
||
{
|
||
try
|
||
{
|
||
VE::EMIT(event_type::WINDOW_CLOSE, nullptr);
|
||
}
|
||
catch(std::exception& e)
|
||
{
|
||
hack::log()("VE_ERROR: ", e.what());
|
||
}
|
||
});
|
||
|
||
glfwSetWindowFocusCallback(m_win, [](GLFWwindow* w, int focused)
|
||
{
|
||
try
|
||
{
|
||
VE::EMIT(event_type::WINDOW_FOCUS, focused);
|
||
}
|
||
catch(std::exception& e)
|
||
{
|
||
hack::log()("VE_ERROR: ", e.what());
|
||
}
|
||
});
|
||
}
|
||
|
||
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);
|
||
}
|
||
}
|