init
This commit is contained in:
commit
a8ebc7a78f
5 changed files with 348 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
.idea
|
||||
cmake-*
|
67
CMakeLists.txt
Normal file
67
CMakeLists.txt
Normal file
|
@ -0,0 +1,67 @@
|
|||
cmake_minimum_required(VERSION 4.0)
|
||||
project(WindowGlfwGlLib CXX C)
|
||||
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IS_IPO_SUPPORTED OUTPUT IPO_OUTPUT_VERBOSE)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(GLEW REQUIRED)
|
||||
find_package(glfw3 REQUIRED)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(Jemalloc REQUIRED jemalloc)
|
||||
|
||||
set(COMPILE_FLAGS
|
||||
-pipe
|
||||
-march=native
|
||||
-mtune=native
|
||||
-Wall
|
||||
-Wextra
|
||||
-Winline
|
||||
-pedantic
|
||||
-pedantic-errors
|
||||
-Wnrvo
|
||||
)
|
||||
|
||||
set(COMPILE_OPTIMIZED_FLAGS
|
||||
-fno-plt
|
||||
-fuse-ld=mold
|
||||
-funroll-loops
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
-fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free
|
||||
)
|
||||
|
||||
set(LINKER_OPTIONS
|
||||
-Wl,--sort-common,--as-needed
|
||||
)
|
||||
|
||||
set(LINKER_OPTIMIZED_OPTIONS
|
||||
-Wl,--gc-sections
|
||||
-fuse-ld=mold
|
||||
)
|
||||
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
|
||||
set(COMPILE_FLAGS -stdlib=libc++ ${COMPILE_FLAGS})
|
||||
set(LINKER_FLAGS ${LINKER_FLAGS} c++)
|
||||
|
||||
set(COMPILE_OPTIMIZED_FLAGS ${COMPILE_OPTIMIZED_FLAGS} -fwhole-program-vtables)
|
||||
set(LINKER_OPTIMIZED_OPTIONS ${LINKER_OPTIMIZED_OPTIONS} -fwhole-program-vtables)
|
||||
elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
|
||||
set(LINKER_FLAGS ${LINKER_FLAGS} stdc++)
|
||||
|
||||
set(COMPILE_OPTIMIZED_FLAGS ${COMPILE_OPTIMIZED_FLAGS} -fdevirtualize-at-ltrans)
|
||||
set(LINKER_OPTIMIZED_OPTIONS ${LINKER_OPTIMIZED_OPTIONS} -fdevirtualize-at-ltrans)
|
||||
endif ()
|
||||
|
||||
add_library(WindowGlfwGlLib SHARED window.cpp window.hpp basic_data.hpp)
|
||||
target_precompile_headers(${PROJECT_NAME} PUBLIC window.hpp basic_data.hpp)
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC GLFW_INCLUDE_NONE PRIVATE $<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:GNU>>:_GLIBCXX_DEBUG>)
|
||||
target_compile_options(${PROJECT_NAME} PUBLIC ${COMPILE_FLAGS} $<$<CONFIG:Release>:${COMPILE_OPTIMIZED_FLAGS}>)
|
||||
target_link_options(${PROJECT_NAME} PUBLIC ${LINKER_OPTIONS} $<$<CONFIG:Release>:${LINKER_OPTIMIZED_OPTIONS}>)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC $<$<CONFIG:Release>:${Jemalloc_LIBRARIES}> OpenGL::GL GLEW::GLEW glfw)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 23 CXX_EXTENSIONS OFF)
|
||||
if(IS_IPO_SUPPORTED)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
|
||||
else()
|
||||
message(WARNING "IPO is not supported: ${IPO_OUTPUT_VERBOSE}")
|
||||
endif()
|
33
basic_data.hpp
Normal file
33
basic_data.hpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef POC2DMODULAR_BASIC_DATA_HPP
|
||||
#define POC2DMODULAR_BASIC_DATA_HPP
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace data {
|
||||
class BasicData {
|
||||
public:
|
||||
|
||||
const std::string name{ "Basic" };
|
||||
|
||||
BasicData() = delete;
|
||||
|
||||
explicit BasicData(std::string name) : name(std::move(name)) {}
|
||||
|
||||
virtual ~BasicData() noexcept = default;
|
||||
|
||||
virtual void key_callback(int key, int scancode, int action, int mods) = 0;
|
||||
|
||||
virtual void cursor_position_callback(double xpos, double ypos) = 0;
|
||||
|
||||
virtual void scroll_callback(double xoffset, double yoffset) = 0;
|
||||
|
||||
virtual void window_pos(int xpos, int ypos) = 0;
|
||||
|
||||
virtual void window_size(int width, int height) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //POC2DMODULAR_BASIC_DATA_HPP
|
157
window.cpp
Normal file
157
window.cpp
Normal file
|
@ -0,0 +1,157 @@
|
|||
#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);
|
||||
}
|
||||
}
|
89
window.hpp
Normal file
89
window.hpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
#ifndef POC2DMODULAR_WINDOW_HPP
|
||||
#define POC2DMODULAR_WINDOW_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace data {
|
||||
class BasicData;
|
||||
}
|
||||
|
||||
namespace gui {
|
||||
class Window final {
|
||||
public:
|
||||
using modulesType = std::unordered_map<std::string, data::BasicData *>;
|
||||
using windowPtr = GLFWwindow *;
|
||||
|
||||
private:
|
||||
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods);
|
||||
|
||||
static void cursor_position_callback(GLFWwindow *window, double xpos, double ypos);
|
||||
|
||||
static void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
|
||||
|
||||
static void window_size_callback(GLFWwindow *window, int width, int height);
|
||||
|
||||
static void window_pos_callback(GLFWwindow *window, int xpos, int ypos);
|
||||
|
||||
static void delete_glfw_window(GLFWwindow *glfWwindow) {
|
||||
glfwDestroyWindow(glfWwindow);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
static std::uint_fast8_t count_instance;
|
||||
|
||||
std::unique_ptr<GLFWwindow, decltype(&delete_glfw_window)> wwindow{ nullptr, delete_glfw_window };
|
||||
|
||||
modulesType modules;
|
||||
|
||||
explicit Window(const bool debugOpengl,
|
||||
const GLFWframebuffersizefun framebufferCallback,
|
||||
GLFWwindow *shared,
|
||||
std::initializer_list<modulesType::value_type> initializer);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static bool init_glfw(GLFWerrorfun errorCallback) noexcept;
|
||||
|
||||
Window() noexcept = delete;
|
||||
|
||||
Window(Window &&window) noexcept = default;
|
||||
|
||||
[[nodiscard]] friend std::optional<Window> create_window(
|
||||
const GLFWerrorfun errorCallback,
|
||||
GLFWframebuffersizefun framebufferCallback,
|
||||
const bool debugOpengl,
|
||||
GLFWwindow *shared,
|
||||
std::initializer_list<Window::modulesType::value_type> initializer) noexcept;
|
||||
|
||||
~Window() noexcept;
|
||||
|
||||
[[nodiscard]] const std::unique_ptr<GLFWwindow, decltype(&delete_glfw_window)> &get_window() const noexcept;
|
||||
|
||||
[[nodiscard]] bool should_close() const noexcept;
|
||||
|
||||
void swap_buffers() const noexcept;
|
||||
|
||||
void add_module(data::BasicData &module);
|
||||
|
||||
void delete_module(const std::string &module);
|
||||
|
||||
/**
|
||||
* \brief Make window's OpenGL context current
|
||||
*/
|
||||
void get_context() const noexcept;
|
||||
|
||||
Window &operator=(Window &&other) noexcept = default;
|
||||
};
|
||||
|
||||
void color_10_bits() noexcept;
|
||||
|
||||
bool check_color_depth(int color_depth) noexcept;
|
||||
|
||||
void opengl_debug() noexcept;
|
||||
}
|
||||
|
||||
|
||||
#endif //POC2DMODULAR_WINDOW_HPP
|
Loading…
Add table
Add a link
Reference in a new issue