157 lines
5.9 KiB
C++
157 lines
5.9 KiB
C++
#include "window.hpp"
|
|
#include <algorithm>
|
|
#include <GL/glew.h>
|
|
|
|
static void internalFramebufferCallback([[maybe_unused]] GLFWwindow *glfWwindow, const int width, const int height) {
|
|
glViewport(0, 0, width, height);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
}
|
|
|
|
namespace gui {
|
|
static bool init = false;
|
|
|
|
std::uint_fast8_t Window::count_instance = 0;
|
|
|
|
Window::Window(const bool debugOpengl,
|
|
const GLFWframebuffersizefun framebufferCallback,
|
|
GLFWwindow *shared,
|
|
const std::initializer_list<modulesType::value_type> initializer) : modules(initializer) {
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
|
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, debugOpengl ? GLFW_TRUE : GLFW_FALSE);
|
|
wwindow = std::unique_ptr<GLFWwindow, decltype(&delete_glfw_window)>(
|
|
glfwCreateWindow(720, 1280, "Billy Sheet tracker", nullptr, shared),
|
|
delete_glfw_window
|
|
);
|
|
if (!wwindow) {
|
|
glfwTerminate();
|
|
init = false;
|
|
count_instance = 0;
|
|
return;
|
|
}
|
|
glfwMakeContextCurrent(wwindow.get());
|
|
glewExperimental = true;
|
|
if (glewInit() != GLEW_OK) {
|
|
wwindow.reset(nullptr);
|
|
glfwTerminate();
|
|
init = false;
|
|
count_instance = 0;
|
|
return;
|
|
}
|
|
++count_instance;
|
|
glfwSetFramebufferSizeCallback(wwindow.get(),
|
|
framebufferCallback != nullptr ? framebufferCallback : internalFramebufferCallback);
|
|
|
|
glfwSwapInterval(1); // VSync on
|
|
glfwSetKeyCallback(wwindow.get(), key_callback);
|
|
glfwSetScrollCallback(wwindow.get(), scroll_callback);
|
|
glfwSetCursorPosCallback(wwindow.get(), cursor_position_callback);
|
|
glfwSetWindowSizeCallback(wwindow.get(), window_size_callback);
|
|
glfwSetWindowPosCallback(wwindow.get(), window_pos_callback);
|
|
glfwSetWindowUserPointer(wwindow.get(), &modules);
|
|
}
|
|
|
|
Window::~Window() noexcept {
|
|
if (count_instance > 0) {
|
|
--count_instance;
|
|
}
|
|
}
|
|
|
|
const std::unique_ptr<GLFWwindow, decltype(&Window::delete_glfw_window)> &Window::get_window() const noexcept {
|
|
return wwindow;
|
|
}
|
|
|
|
bool Window::should_close() const noexcept {
|
|
return glfwWindowShouldClose(wwindow.get());
|
|
}
|
|
|
|
void Window::swap_buffers() const noexcept {
|
|
glfwSwapBuffers(wwindow.get());
|
|
}
|
|
|
|
void Window::key_callback(GLFWwindow *window, const int key, const int scancode, const int action, const int mods) {
|
|
auto *modules = static_cast<modulesType *>(glfwGetWindowUserPointer(window));
|
|
std::ranges::for_each(*modules,
|
|
[=](modulesType::reference item) { item.second->key_callback(key, scancode, action, mods); });
|
|
}
|
|
|
|
void Window::cursor_position_callback(GLFWwindow *window, const double xpos, const double ypos) {
|
|
auto *modules = static_cast<modulesType *>(glfwGetWindowUserPointer(window));
|
|
std::ranges::for_each(*modules,
|
|
[=](modulesType::reference item) { item.second->cursor_position_callback(xpos, ypos); });
|
|
}
|
|
|
|
void Window::scroll_callback(GLFWwindow *window, const double xoffset, const double yoffset) {
|
|
auto *modules = static_cast<modulesType *>(glfwGetWindowUserPointer(window));
|
|
std::ranges::for_each(*modules,
|
|
[=](modulesType::reference item) { item.second->scroll_callback(xoffset, yoffset); });
|
|
}
|
|
|
|
void Window::window_size_callback(GLFWwindow *window, const int width, const int height) {
|
|
auto *modules = static_cast<modulesType *>(glfwGetWindowUserPointer(window));
|
|
std::ranges::for_each(*modules,
|
|
[=](modulesType::reference item) { item.second->window_size(width, height); });
|
|
}
|
|
|
|
void Window::window_pos_callback(GLFWwindow *window, const int xpos, const int ypos) {
|
|
auto *modules = static_cast<modulesType *>(glfwGetWindowUserPointer(window));
|
|
std::ranges::for_each(*modules,
|
|
[=](modulesType::reference item) { item.second->window_pos(xpos, ypos); });
|
|
}
|
|
|
|
void Window::add_module(data::BasicData &module) {
|
|
modules.emplace(module.name, &module);
|
|
}
|
|
|
|
void Window::delete_module(const std::string &module) {
|
|
modules.erase(module);
|
|
}
|
|
|
|
void Window::get_context() const noexcept {
|
|
glfwMakeContextCurrent(wwindow.get());
|
|
}
|
|
|
|
std::optional<Window> create_window(
|
|
const GLFWerrorfun errorCallback,
|
|
const GLFWframebuffersizefun framebufferCallback,
|
|
const bool debugOpengl,
|
|
GLFWwindow *shared,
|
|
const std::initializer_list<Window::modulesType::value_type> initializer
|
|
) noexcept {
|
|
if (!init) {
|
|
glfwSetErrorCallback(errorCallback);
|
|
if (glfwInit() == GLFW_FALSE) {
|
|
return std::nullopt;
|
|
}
|
|
init = true;
|
|
}
|
|
if (Window win{ debugOpengl, framebufferCallback, shared, initializer }; win.get_window()) {
|
|
return win;
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
bool Window::init_glfw(const GLFWerrorfun errorCallback) noexcept {
|
|
glfwSetErrorCallback(errorCallback);
|
|
init = glfwInit() == GLFW_TRUE;
|
|
return init;
|
|
}
|
|
|
|
void color_10_bits() noexcept {
|
|
glfwWindowHint(GLFW_RED_BITS, 10);
|
|
glfwWindowHint(GLFW_GREEN_BITS, 10);
|
|
glfwWindowHint(GLFW_BLUE_BITS, 10);
|
|
}
|
|
|
|
bool check_color_depth(const int color_depth) noexcept {
|
|
GLint redBits = 0, greenBits = 0, blueBits = 0;
|
|
glGetIntegerv(GL_RED_BITS, &redBits);
|
|
glGetIntegerv(GL_GREEN_BITS, &greenBits);
|
|
glGetIntegerv(GL_BLUE_BITS, &blueBits);
|
|
return redBits == color_depth && greenBits == color_depth && blueBits == color_depth;
|
|
}
|
|
|
|
void opengl_debug() noexcept {
|
|
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
|
}
|
|
}
|