#include #include "gl/glad/glad.h" #include #include #include struct window_data { lua_State *L; int framebuffer_size_callback; }; struct window_data * create_window_data(lua_State *L) { struct window_data *wdata = malloc(sizeof(struct window_data)); if (wdata == NULL) return NULL; wdata->L = L; wdata->framebuffer_size_callback = LUA_NOREF; return wdata; } int window_create(lua_State *L); int window_destroy(lua_State *L); int window_make_context_current(lua_State *L); int window_set_hint(lua_State *L); int window_should_close(lua_State *L); int window_poll_events(lua_State *L); int window_swap_buffers(lua_State *L); int window_set_framebuffer_size_callback(lua_State *L); int window_get_time(lua_State *L); void setup_window(lua_State *L, int honey_index) { int hint_types = hs_create_table(L, hs_str_int("contextVersionMajor", GLFW_CONTEXT_VERSION_MAJOR), hs_str_int("contextVersionMinor", GLFW_CONTEXT_VERSION_MINOR), hs_str_int("openGlProfile", GLFW_OPENGL_PROFILE), ); int profile_types = hs_create_table(L, hs_str_int("openGlCoreProfile", GLFW_OPENGL_CORE_PROFILE), ); hs_create_table(L, hs_str_cfunc("create", window_create), hs_str_cfunc("destroy", window_destroy), hs_str_cfunc("makeContextCurrent", window_make_context_current), hs_str_cfunc("setHint", window_set_hint), hs_str_cfunc("shouldClose", window_should_close), hs_str_cfunc("pollEvents", window_poll_events), hs_str_cfunc("swapBuffers", window_swap_buffers), hs_str_cfunc("setFramebufferSizeCallback", window_set_framebuffer_size_callback), hs_str_cfunc("getTime", window_get_time), hs_str_tbl("hintType", hint_types), hs_str_tbl("profileType", profile_types), ); lua_setfield(L, honey_index, "window"); } static void framebuffer_size_callback_(GLFWwindow *win, int width, int height) { struct window_data *wdata = glfwGetWindowUserPointer(win); if (wdata->framebuffer_size_callback != LUA_NOREF) { hs_rload(wdata->L, wdata->framebuffer_size_callback); lua_pushlightuserdata(wdata->L, win); lua_pushinteger(wdata->L, width); lua_pushinteger(wdata->L, height); hs_call(wdata->L, 3, 0); } } int window_create(lua_State *L) { lua_Integer width, height; char *title; hs_parse_args(L, hs_int(width), hs_int(height), hs_str(title)); GLFWwindow *win = glfwCreateWindow(width, height, title, NULL, NULL); if (win == NULL) hs_throw_error(L, "failed to create window"); struct window_data *wdata = create_window_data(L); glfwSetWindowUserPointer(win, wdata); glfwSetFramebufferSizeCallback(win, framebuffer_size_callback_); lua_pushlightuserdata(L, win); return 1; } int window_destroy(lua_State *L) { void *ptr; hs_parse_args(L, hs_light(ptr)); GLFWwindow *win = ptr; void *wdata = glfwGetWindowUserPointer(win); if (wdata != NULL) { free(wdata); glfwSetWindowUserPointer(win, NULL); } glfwDestroyWindow(win); return 0; } int window_make_context_current(lua_State *L) { void *ptr; hs_parse_args(L, hs_light(ptr)); GLFWwindow *win = ptr; glfwMakeContextCurrent(win); return 0; } int window_set_hint(lua_State *L) { lua_Integer hint, value; hs_parse_args(L, hs_int(hint), hs_int(value)); glfwWindowHint(hint, value); return 0; } int window_should_close(lua_State *L) { void *ptr; hs_parse_args(L, hs_light(ptr)); GLFWwindow *win = ptr; lua_pushboolean(L, glfwWindowShouldClose(win)); return 1; } int window_poll_events(lua_State *L) { glfwPollEvents(); return 0; } int window_swap_buffers(lua_State *L) { void *ptr; hs_parse_args(L, hs_light(ptr)); GLFWwindow *win = ptr; glfwSwapBuffers(win); return 0; } int window_set_framebuffer_size_callback(lua_State *L) { void *ptr; int func; hs_parse_args(L, hs_light(ptr), hs_func(func)); GLFWwindow *win = ptr; struct window_data *wdata = glfwGetWindowUserPointer(win); lua_pushvalue(L, func); wdata->framebuffer_size_callback = hs_rstore(L); return 0; } int window_get_time(lua_State *L) { lua_pushnumber(L, glfwGetTime()); return 1; }