#include "ogl.hpp"
bool glerr(const char* prefix, bool always) {
const char* estr = "[UNKNOWN]"; // TODO: gluErrorString(e)
GLenum e = glGetError();
switch (e) {
case GL_NO_ERROR:
if (!always) return false;
estr = "GL_NO_ERROR";
break;
case GL_INVALID_ENUM:
estr = "GL_INVALID_ENUM";
break;
case GL_INVALID_VALUE:
estr = "GL_INVALID_VALUE";
break;
case GL_INVALID_OPERATION:
estr = "GL_INVALID_OPERATION";
break;
case GL_STACK_OVERFLOW:
estr = "GL_STACK_OVERFLOW";
break;
case GL_STACK_UNDERFLOW:
estr = "GL_STACK_UNDERFLOW";
break;
case GL_OUT_OF_MEMORY:
estr = "GL_OUT_OF_MEMORY";
break;
}
LOG("%sGL err 0x%x - %s", prefix?:"", e, estr);
return true;
}
Window* Window::inst = NULL;
static GLfloat scale(unsigned val, unsigned max) {
assert(val<=max);
const GLfloat mid = ((GLfloat)max) / 2.0f;
return (((GLfloat)val) - mid) / mid;
}
GLfloat Window::px2iso_x(unsigned x) const {
return scale(x, w-1);
}
GLfloat Window::px2iso_y(unsigned y) const {
return scale(y, h-1);
}
unsigned Window::iso2px_x(GLfloat x) const {
return ((x+1.0f)*0.5f) * (GLfloat)w;
}
unsigned Window::iso2px_y(GLfloat y) const {
return ((y+1.0f)*0.5f) * (GLfloat)h;
}
Window* Window::getInst(unsigned w, unsigned h, bool fullscreen, const char* name) {
if (inst) return NULL; // singleton and only once atm
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
if (fullscreen) {
w = mode->width;
h = mode->height;
} else if (!w || !h) { // windowed w/o explicit dimensions
w = mode->width / 2;
h = mode->height / 2;
} else {
w = MIN((int)w, mode->width);
h = MIN((int)h, mode->height);
}
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* win = glfwCreateWindow(w, h, name?:"OpenGL", fullscreen? glfwGetPrimaryMonitor(): NULL, NULL); // TODO: error detection
glfwMakeContextCurrent(win);
glfwSwapInterval(1); // limit framerate to vsync
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
return NULL;
}
(void)glGetError(); // https://www.opengl.org/wiki/OpenGL_Loading_Library#Initialization_of_GLEW_1.13.0_and_earlier
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST); // TODO: only if needed?
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
return inst = new Window(win, w, h);
}
Window::~Window() {
glfwDestroyWindow(window);
glfwTerminate();
}
void Window::shouldClose(bool b) {
glfwSetWindowShouldClose(window, b? GL_TRUE: GL_FALSE);
}
bool Window::shouldClose() const {
return glfwWindowShouldClose(window);
}