184 lines
5.3 KiB
C++
184 lines
5.3 KiB
C++
#include "Window.hpp"
|
|
|
|
namespace nb {
|
|
|
|
std::map<GLFWwindow*, Window*> Window::WindowContexts = {};
|
|
std::map<int, int> Window::GLFWHints = {};
|
|
bool Window::StrictInitialization = true;
|
|
bool Window::_glfw_init = false;
|
|
Window* Window::_current = nullptr;
|
|
static std::map<int, int> defailt_window_hints = {
|
|
{GLFW_CONTEXT_VERSION_MAJOR, 3},
|
|
{GLFW_CONTEXT_VERSION_MINOR, 1},
|
|
{GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE}
|
|
#ifdef _NB_GL_DEBUG_ON
|
|
, {GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE}
|
|
#endif
|
|
};
|
|
|
|
using OpenGLErrorCodes = OpenGLError::Codes;
|
|
const std::string OpenGLError::type = "nb::OpenGLError";
|
|
const ErrorCodeMap OpenGLError::ErrorMessages = {
|
|
{OpenGLErrorCodes::UNDEFINED, "Error"},
|
|
{OpenGLErrorCodes::INIT_FAILED, "GLFW initialization failed"},
|
|
{OpenGLErrorCodes::GLFW_INTIALIZED, "GLFW has already been initialized"},
|
|
{OpenGLErrorCodes::GLAD_FAILED, "GLAD initialization failed"}
|
|
};
|
|
|
|
using WindowErrorCodes = WindowError::Codes;
|
|
const std::string WindowError::type = "nb::WindowError";
|
|
const ErrorCodeMap WindowError::ErrorMessages = {
|
|
{WindowErrorCodes::UNDEFINED, "Error"},
|
|
{WindowErrorCodes::INITIALIZED_WINDOW, "Window already initialized"},
|
|
{WindowErrorCodes::NO_GLFW, "GLFW has not been initialized"},
|
|
{WindowErrorCodes::INIT_FAILED, "Could not intialized window"}
|
|
};
|
|
|
|
GLError::GLError(const std::string& msg) : std::runtime_error(msg) {}
|
|
|
|
int Window::getGLFWHint(int hint_key) {
|
|
if (GLFWHints.find(hint_key) == GLFWHints.end()) {
|
|
return 0;
|
|
} else {
|
|
return GLFWHints.at(hint_key);
|
|
}
|
|
}
|
|
|
|
int Window::setGLFWHint(int hint_key, int hint_val) {
|
|
if (Window::_glfw_init) {
|
|
THROW(OpenGLError(OpenGLErrorCodes::GLFW_INTIALIZED));
|
|
} else {
|
|
GLFWHints[hint_key] = hint_val;
|
|
}
|
|
return GLFWHints[hint_key];
|
|
}
|
|
|
|
Window* Window::getCurrent() {
|
|
return _current;
|
|
}
|
|
|
|
bool Window::checkKillGLFW() {
|
|
if(Window::WindowContexts.size() == 0 && _glfw_init) {
|
|
glfwTerminate();
|
|
Window::_glfw_init = false;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Window::Window(const uint16_t x, const uint16_t y, const char* initName, GLFWmonitor* initMonitor, GLFWwindow* initWindow) {
|
|
if (!Window::_glfw_init) {
|
|
for (const auto& hint : Window::GLFWHints) {
|
|
glfwInitHint(hint.first, hint.second);
|
|
}
|
|
int glfwResponse = glfwInit();
|
|
if (glfwResponse) {
|
|
Window::_glfw_init = true;
|
|
} else {
|
|
if (Window::StrictInitialization) {
|
|
THROW(OpenGLError(OpenGLErrorCodes::INIT_FAILED));
|
|
}
|
|
}
|
|
}
|
|
|
|
windowSize = {x, y};
|
|
_aspect_ratio = float(x)/float(y);
|
|
windowName = std::string(initName);
|
|
monitor = initMonitor;
|
|
shareWindow = initWindow;
|
|
|
|
for (const auto& hint: defailt_window_hints) {
|
|
windowHints[hint.first] = hint.second;
|
|
}
|
|
}
|
|
|
|
Window::Window(const std::array<uint16_t, 2> initSize, const char* initName, GLFWmonitor* initMonitor, GLFWwindow* initWindow) :
|
|
Window(initSize[0], initSize[1], initName, initMonitor, initWindow){}
|
|
|
|
Window::~Window() {
|
|
glfwSetWindowShouldClose(window, true);
|
|
glfwDestroyWindow(window);
|
|
Window::WindowContexts.erase(window);
|
|
if (Window::WindowContexts.size()==0) {
|
|
glfwTerminate();
|
|
}
|
|
}
|
|
|
|
void Window::setCurrent() {
|
|
_current = this;
|
|
glfwMakeContextCurrent(window);
|
|
}
|
|
|
|
int Window::getWindowHint(int hint_key) const {
|
|
if (windowHints.find(hint_key) == windowHints.end()) {
|
|
return 0;
|
|
} else {
|
|
return windowHints.at(hint_key);
|
|
}
|
|
}
|
|
|
|
int Window::setWindowHint(int hint_key, int hint_val) {
|
|
if (_init) {
|
|
THROW(WindowError(WindowErrorCodes::INITIALIZED_WINDOW));
|
|
} else {
|
|
windowHints[hint_key] = hint_val;
|
|
}
|
|
return windowHints[hint_key];
|
|
}
|
|
|
|
int Window::init() {
|
|
if (!_glfw_init) {
|
|
THROW(WindowError(WindowErrorCodes::NO_GLFW));
|
|
}
|
|
for (const auto& hint : windowHints) {
|
|
glfwWindowHint(hint.first, hint.second);
|
|
}
|
|
|
|
window = glfwCreateWindow(windowSize[0], windowSize[1], windowName.c_str(), monitor, shareWindow);
|
|
if (window == NULL) {
|
|
Window::WindowContexts.erase(window);
|
|
if (Window::WindowContexts.size()==0 && Window::_glfw_init) { glfwTerminate(); }
|
|
if (Window::StrictInitialization) {
|
|
THROW(WindowError(WindowErrorCodes::INIT_FAILED));
|
|
}
|
|
}
|
|
glfwMakeContextCurrent(window);
|
|
Window::WindowContexts[window] = this;
|
|
|
|
gladResponse = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
|
if (!gladResponse) {
|
|
Window::checkKillGLFW();
|
|
if (Window::StrictInitialization) {
|
|
THROW(OpenGLError(OpenGLErrorCodes::GLAD_FAILED));
|
|
}
|
|
}
|
|
|
|
_init = true;
|
|
glViewport(0, 0, windowSize[0], windowSize[1]);
|
|
return gladResponse;
|
|
}
|
|
|
|
GLFWwindow* Window::getWindow() const {
|
|
return window;
|
|
}
|
|
|
|
float Window::getAspectRatio() const { return _aspect_ratio; }
|
|
|
|
std::array<uint16_t, 2> Window::getSize() const {
|
|
return windowSize;
|
|
}
|
|
|
|
std::string Window::getName() const {
|
|
return windowName;
|
|
}
|
|
|
|
void Window::resize(const std::array<uint16_t, 2> newSize) {
|
|
windowSize = newSize;
|
|
_aspect_ratio = float(newSize[0]) / float(newSize[1]);
|
|
glViewport(0, 0, windowSize[0], windowSize[1]);
|
|
glfwSetWindowSize(window, windowSize[0], windowSize[1]);
|
|
}
|
|
|
|
void Window::resize(const uint16_t x, const uint16_t y) { resize({x, y}); }
|
|
|
|
}; |