Lots of stuff, ending with Window restruct
This commit is contained in:
@@ -22,7 +22,9 @@ const ErrorCodeMap GLFWError::ErrorMessages = {
|
||||
{GLFWCodes::UNDEFINED, "Error"},
|
||||
{GLFWCodes::INIT_FAILED, "GLFW initialization failed"},
|
||||
{GLFWCodes::GLFW_INTIALIZED, "GLFW has already been initialized"},
|
||||
{GLFWCodes::GLAD_FAILED, "GLAD initialization failed"}
|
||||
{GLFWCodes::GLAD_FAILED, "GLAD initialization failed"},
|
||||
{GLFWCodes::NOT_MAIN, "Action can only be done on main thread"},
|
||||
{GLFWCodes::WINDOW_FAILED, "Failed to initialize window"}
|
||||
};
|
||||
|
||||
using WindowErrorCodes = WindowError::Codes;
|
||||
@@ -34,6 +36,9 @@ const ErrorCodeMap WindowError::ErrorMessages = {
|
||||
{WindowErrorCodes::INIT_FAILED, "Could not intialized window"}
|
||||
};
|
||||
|
||||
|
||||
// class Window
|
||||
|
||||
int Window::getGLFWHint(int hint_key) {
|
||||
if (GLFWHints.find(hint_key) == GLFWHints.end()) {
|
||||
return 0;
|
||||
@@ -183,4 +188,148 @@ void Window::resize(const std::array<uint16_t, 2> newSize) {
|
||||
|
||||
void Window::resize(const uint16_t x, const uint16_t y) { resize({x, y}); }
|
||||
|
||||
// class OGLWindow
|
||||
|
||||
std::atomic<bool> OGLWindow::_glfwInitialized = false;
|
||||
thread_local std::shared_ptr<OGLWindow> OGLWindow::_currWindow = nullptr;
|
||||
thread_local GLFWwindow* OGLWindow::_currArena = nullptr;
|
||||
std::atomic<unsigned int> OGLWindow::_count = 0;
|
||||
|
||||
bool OGLWindow::InitGLFW(const std::vector<GLFWHint>& hints) {
|
||||
if (nb::MainTID != GetTID()) {
|
||||
THROW(GLFWError(GLFWError::NOT_MAIN));
|
||||
}
|
||||
if (!IsGLFWInitialized()) {
|
||||
for (const auto& hint : hints) {
|
||||
glfwInitHint(hint[0], hint[1]);
|
||||
}
|
||||
if (glfwInit()) {
|
||||
OGLWindow::_glfwInitialized.store(true, std::memory_order_release);
|
||||
} else {
|
||||
THROW(GLFWError(GLFWError::INIT_FAILED));
|
||||
}
|
||||
}
|
||||
return IsGLFWInitialized();
|
||||
}
|
||||
|
||||
bool OGLWindow::TerminateGLFW() {
|
||||
if (nb::MainTID != GetTID()) {
|
||||
THROW(GLFWError(GLFWError::NOT_MAIN));
|
||||
}
|
||||
if (IsGLFWInitialized()) {
|
||||
glfwTerminate();
|
||||
OGLWindow::_glfwInitialized.store(false, std::memory_order_release);
|
||||
}
|
||||
return !IsGLFWInitialized();
|
||||
}
|
||||
|
||||
void OGLWindow::SetHintInteger(const std::array<int, 2>& hint) {
|
||||
CheckForMainThread();
|
||||
glfwWindowHint(hint[0], hint[1]);
|
||||
}
|
||||
|
||||
void OGLWindow::SetHintString(const std::tuple<int, std::string>& hint) {
|
||||
CheckForMainThread();
|
||||
glfwWindowHintString(std::get<0>(hint), std::get<1>(hint).c_str());
|
||||
}
|
||||
|
||||
std::shared_ptr<OGLWindow> OGLWindow::MakeCurrent(const std::shared_ptr<OGLWindow>& window) {
|
||||
auto tmp = _currWindow;
|
||||
_currWindow = window;
|
||||
if (window) {
|
||||
glfwMakeContextCurrent(_currWindow->_window_ptr);
|
||||
_currArena = window->_arena;
|
||||
} else {
|
||||
glfwMakeContextCurrent(nullptr);
|
||||
_currArena = nullptr;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
OGLWindow::OGLWindow(
|
||||
unsigned int x,
|
||||
unsigned int y,
|
||||
const std::string& title,
|
||||
const std::vector<std::array<int, 2>>& integerHints,
|
||||
const std::vector<std::tuple<int, std::string>>& stringHints
|
||||
) : _title(title) {
|
||||
CheckForMainThread();
|
||||
InitGLFW();
|
||||
for (const auto& hint : integerHints) {
|
||||
SetHintInteger(hint);
|
||||
}
|
||||
for (const auto& hint : stringHints) {
|
||||
SetHintString(hint);
|
||||
}
|
||||
_window_ptr = glfwCreateWindow(
|
||||
x,
|
||||
y,
|
||||
_title.c_str(),
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
if (_window_ptr == NULL) {
|
||||
THROW(GLFWError(GLFWError::Codes::WINDOW_FAILED));
|
||||
}
|
||||
_arena = _window_ptr;
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
||||
THROW(GLFWError(GLFWError::Codes::GLAD_FAILED));
|
||||
}
|
||||
OGLWindow::_count.fetch_add(1);
|
||||
}
|
||||
|
||||
std::shared_ptr<OGLWindow> OGLWindow::CreateWindow(
|
||||
unsigned int x,
|
||||
unsigned int y,
|
||||
const std::string& title,
|
||||
const std::vector<std::array<int, 2>>& integerHints,
|
||||
const std::vector<std::tuple<int, std::string>>& stringHints
|
||||
) {
|
||||
return std::shared_ptr<OGLWindow>( new OGLWindow(
|
||||
x,
|
||||
y,
|
||||
title,
|
||||
integerHints,
|
||||
stringHints
|
||||
) );
|
||||
}
|
||||
|
||||
OGLWindow::~OGLWindow() {
|
||||
CheckForMainThread();
|
||||
if (_window_ptr) {
|
||||
if (_window_ptr == _currWindow->_window_ptr) {
|
||||
_currWindow = nullptr;
|
||||
_currArena = nullptr;
|
||||
}
|
||||
glfwDestroyWindow(_window_ptr);
|
||||
_count.fetch_add(-1);
|
||||
if (!_count.load()) {
|
||||
TerminateGLFW();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int OGLWindow::getWindowAttribute(int attr) const {
|
||||
CheckForMainThread();
|
||||
return glfwGetWindowAttrib(_window_ptr, attr);
|
||||
}
|
||||
|
||||
std::array<int, 2> OGLWindow::getSize() const {
|
||||
CheckForMainThread();
|
||||
int x, y;
|
||||
glfwGetWindowSize(_window_ptr, &x, &y);
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
void OGLWindow::setSize(unsigned int x, unsigned int y) {
|
||||
CheckForMainThread();
|
||||
glfwSetWindowSize(_window_ptr, x, y);
|
||||
}
|
||||
|
||||
void OGLWindow::setTitle(const std::string& name) {
|
||||
CheckForMainThread();
|
||||
_title = name;
|
||||
glfwSetWindowTitle(_window_ptr, _title.c_str());
|
||||
}
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user