#include // Include Windows.h before GLFW to avoid macro redefinition warnings. #define WIN32_LEAN_AND_MEAN #include #define GLFW_INCLUDE_NONE // Do not include OpenGL headers. #include #define GLFW_EXPOSE_NATIVE_WIN32 #include #include #include #include typedef struct Window { GLFWwindow* glfw_window; } Window; static char glfw_error[1024] = {}; static void glfw_error_callback(int error, const char* description) { sprintf_s(glfw_error, sizeof(glfw_error), "GLFW error %d: %s", error, description); } bool window_global_init() { glfwSetErrorCallback(glfw_error_callback); return glfwInit() == GLFW_TRUE; } void window_global_quit() { glfwTerminate(); } const char* window_get_error(Window* wnd) { assert(wnd); return glfw_error; } Window* window_init(int width, int height, const char* title) { Window* wnd = calloc(1, sizeof(Window)); if (!wnd) { return 0; } // GLFW by default creates an OpenGL context with the window. // Use GLFW_NO_API to tell it not to do so. glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); if ((wnd->glfw_window = glfwCreateWindow( width, height, title, /*monitor=*/NULL, /*share=*/NULL)) == 0) { free(wnd); return 0; } return wnd; } void window_destroy(Window** ppWindow) { assert(ppWindow); Window* wnd = *ppWindow; if (wnd) { glfwDestroyWindow(wnd->glfw_window); free(wnd); *ppWindow = 0; } } HWND window_handle(Window* wnd) { assert(wnd); return glfwGetWin32Window(wnd->glfw_window); } void window_update(Window* wnd) { assert(wnd); glfwPollEvents(); } bool window_should_close(const Window* wnd) { assert(wnd); return glfwWindowShouldClose(wnd->glfw_window) == GLFW_TRUE; }