#include "platform.h" #define RAYMATH_IMPLEMENTATION #include "../vendor/glad/glad.c" #include "GLFW/glfw3.h" typedef struct OS_WindowPlatformData OS_WindowPlatformData; struct OS_WindowPlatformData { OS_WindowEventCallback eventHandler; real64 mouseWheelFrameDX; real64 mouseWheelFrameDY; }; static void os_glfw_onFramebufferResize(GLFWwindow *window, int32 width, int32 height) { OS_Window *osWindow = (OS_Window *)glfwGetWindowUserPointer(window); osWindow->width = width; osWindow->height = height; OS_WindowEvent event = (OS_WindowEvent){.kind=OS_WindowEventKind_Resize, .resize={width, height}}; ((OS_WindowPlatformData *)osWindow->platformData)->eventHandler(&event, osWindow); } static void os_glfw_onMouseScroll(GLFWwindow *window, real64 x, real64 y) { OS_Window *osWindow = (OS_Window *)glfwGetWindowUserPointer(window); } OS_WindowInitResult os_windowInit(Arena *arena, OS_WindowInitParams params) { Scratch scratch = scratchStart(NULL, 0); OS_WindowInitResult result = {.result=NULL, .valid=true}; if (glfwInit()) { const char *windowNameCStr = cstring(scratch.arena, params.name); #ifdef GLFW_WAYLAND_APP_ID glfwWindowHintString(GLFW_WAYLAND_APP_ID, windowNameCStr); #endif glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_SAMPLES, 4); GLFWwindow *glfwWindow = glfwCreateWindow( params.width, params.height, #ifdef DJSTDLIB_DEBUG cstring(scratch.arena, print("%s (djstdlib_debug)", windowNameCStr)), #else windowNameCStr, #endif NULL, NULL); if (glfwWindow != NULL) { glfwMakeContextCurrent(glfwWindow); if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { glViewport(0, 0, params.width, params.height); glfwSwapInterval(1); glfwSetInputMode(glfwWindow, GLFW_CURSOR | GLFW_RAW_MOUSE_MOTION, GLFW_CURSOR_NORMAL); glfwSetWindowSize(glfwWindow, params.width, params.height); glEnable(GL_DEPTH_TEST); glEnable(GL_MULTISAMPLE); glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); //glDebugMessageCallback(glDebugCallback, NULL); OS_Window *osWindow = PushStructZero(arena, OS_Window); OS_WindowPlatformData *platformData = PushStructZero(arena, OS_WindowPlatformData); osWindow->platformData = platformData; platformData->eventHandler = params.eventHandler; platformData->eventHandler = params.eventHandler; osWindow->userData = params.data; osWindow->width = params.width; osWindow->height = params.height; osWindow->handle = glfwWindow; glfwSetWindowUserPointer(glfwWindow, osWindow); glfwSetFramebufferSizeCallback(glfwWindow, os_glfw_onFramebufferResize); glfwSetScrollCallback(glfwWindow, os_glfw_onMouseScroll); result.result = osWindow; } else { print("os_windowInit::Failed to initilaize GLAD\n"); result.valid = false; } } else { print("os_windowInit::Failed to create GLFW window\n"); glfwTerminate(); result.valid = false; } } scratchEnd(scratch); return result; } bool os_windowShouldClose(OS_Window *window) { return (bool)glfwWindowShouldClose((GLFWwindow*)window->handle); } static bool glfwMouse(GLFWwindow *window, int mouseBtnCode) { switch (glfwGetMouseButton(window, mouseBtnCode)) { case GLFW_RELEASE: return false; case GLFW_PRESS: return true; default: return false; } } static bool glfwKey(GLFWwindow *window, int keyCode) { switch (glfwGetKey(window, keyCode)) { case GLFW_RELEASE: return false; case GLFW_PRESS: return true; default: return false; } } void os_windowGetInput(OS_Window *window, OS_Input *input) { *input = (OS_Input){0}; GLFWwindow *handle = (GLFWwindow*)window->handle; input->keyboard.escape = glfwKey(handle, GLFW_KEY_ESCAPE); input->keyboard.enter = glfwKey(handle, GLFW_KEY_ENTER); input->keyboard.space = glfwKey(handle, GLFW_KEY_SPACE); input->keyboard.lshift = glfwKey(handle, GLFW_KEY_LEFT_SHIFT); input->keyboard.w = glfwKey(handle, GLFW_KEY_W); input->keyboard.x = glfwKey(handle, GLFW_KEY_X); input->keyboard.y = glfwKey(handle, GLFW_KEY_Y); input->keyboard.z = glfwKey(handle, GLFW_KEY_Z); input->mouse.btnLeft = glfwMouse(handle, GLFW_MOUSE_BUTTON_LEFT); input->mouse.btnRight = glfwMouse(handle, GLFW_MOUSE_BUTTON_RIGHT); input->mouse.btnMiddle = glfwMouse(handle, GLFW_MOUSE_BUTTON_MIDDLE); real64 mouseX; real64 mouseY; glfwGetCursorPos(handle, &mouseX, &mouseY); input->mouse.point = (Vec2){(real32)mouseX, (real32)mouseY}; input->mouse.scroll.dX = ((OS_WindowPlatformData *)window->platformData)->mouseWheelFrameDX; input->mouse.scroll.dY = ((OS_WindowPlatformData *)window->platformData)->mouseWheelFrameDY; } void os_windowSwapBuffers(OS_Window *window) { glfwSwapBuffers((GLFWwindow*)window->handle); } void os_windowFrameBegin(OS_Window *window) { OS_WindowPlatformData *platformData = (OS_WindowPlatformData*)window->platformData; platformData->mouseWheelFrameDX = 0; platformData->mouseWheelFrameDY = 0; glfwPollEvents(); } void os_windowFrameEnd(OS_Window *window) { real64 end = glfwGetTime(); real64 frameTime = end - window->frame.start; window->frame.fps = 1.0f/frameTime; window->frame.start = glfwGetTime(); }