#include #include #include #include #include "voxel.h" #include "window.h" Window window; _Atomic double delta_time; static void key_callback(GLFWwindow *, i32 key, i32, i32 action, i32) { switch (action) { case GLFW_PRESS: window.key_down[key] = true; window.key_pressed[key] = true; break; case GLFW_RELEASE: window.key_down[key] = false; break; } } static void mouse_move_callback(GLFWwindow *, double xpos, double ypos) { window.mouse_x_last = window.mouse_x; window.moues_y_last = window.mouse_y; window.mouse_x = xpos; window.mouse_y = ypos; } static void mouse_button_callback(GLFWwindow *, i32 button, i32 action, i32) { switch (action) { case GLFW_PRESS: window.btn_down[button] = true; window.btn_pressed[button] = true; break; case GLFW_RELEASE: window.btn_down[button] = false; break; } } static void framebuffer_callback(GLFWwindow *, i32 width, i32 height) { window.width = width; window.height = height; window.resize = true; } VOXEL_RESULT window_init(void) { if (glfwInit() == GLFW_FALSE) { ERROR("GLFW failed to initalize"); return VOXEL_ERROR; } memset(&window, 0, sizeof(Window)); delta_time = 0; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); window.window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE, NULL, NULL); if (window.window == NULL) { ERROR("failed to create window"); return VOXEL_ERROR; } glfwSetKeyCallback(window.window, key_callback); glfwSetCursorPosCallback(window.window, mouse_move_callback); glfwSetMouseButtonCallback(window.window, mouse_button_callback); glfwSetFramebufferSizeCallback(window.window, framebuffer_callback); mtx_init(&window.lock, mtx_plain); return VOXEL_OK; } VOXEL_RESULT window_init_gl(void) { glfwMakeContextCurrent(window.window); #ifndef USE_VSYNC glfwSwapInterval(0); #endif glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { ERROR("GLEW failed to initalize"); return VOXEL_ERROR; } return VOXEL_OK; } bool window_closed(void) { return window.close || glfwWindowShouldClose(window.window) == GLFW_TRUE; } void window_update(void) { mtx_lock(&window.lock); // reset "pressed" memset(&window.key_pressed, 0, sizeof(window.key_pressed)); memset(&window.btn_pressed, 0, sizeof(window.btn_pressed)); // update delta time double time = glfwGetTime(); delta_time = time - window.last_time; window.last_time = time; // check for errors GLenum error; while ((error = glGetError()) != GL_NO_ERROR) ERROR("OpenGL error: %d", error); glfwPollEvents(); mtx_unlock(&window.lock); } void window_swap(void) { glfwSwapBuffers(window.window); } void window_close(void) { mtx_lock(&window.lock); glfwDestroyWindow(window.window); glfwTerminate(); mtx_destroy(&window.lock); } bool key_down(i32 key) { bool down; mtx_lock(&window.lock); down = window.key_down[key]; mtx_unlock(&window.lock); return down; } bool key_pressed(i32 key) { bool pressed; mtx_lock(&window.lock); pressed = window.key_pressed[key]; mtx_unlock(&window.lock); return pressed; } bool btn_down(i32 btn) { bool down; mtx_lock(&window.lock); down = window.btn_down[btn]; mtx_unlock(&window.lock); return down; } bool btn_pressed(i32 btn) { bool pressed; mtx_lock(&window.lock); pressed = window.btn_pressed[btn]; mtx_unlock(&window.lock); return pressed; }