From 10288765588673645c1cc0a6e3d2245aff3f9080 Mon Sep 17 00:00:00 2001 From: sanine Date: Tue, 1 Mar 2022 22:42:10 -0600 Subject: add basic window functions, option parsing, and main loop --- src/gl/honey_gl.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++++- src/gl/honey_gl.h | 15 ++--- 2 files changed, 197 insertions(+), 11 deletions(-) (limited to 'src/gl') diff --git a/src/gl/honey_gl.c b/src/gl/honey_gl.c index bbb775f..6a113d1 100644 --- a/src/gl/honey_gl.c +++ b/src/gl/honey_gl.c @@ -1,10 +1,197 @@ #include + +#include + #include "logging/logging.h" #include "gl/honey_gl.h" -int honey_gl_window_ref = LUA_NOREF; -bool honey_gl_setup() +struct honey_window window; + +static int resize_callback_ref = LUA_NOREF; +static int resize_data_ref = LUA_NOREF; + +static int focus_callback_ref = LUA_NOREF; +static int focus_data_ref = LUA_NOREF; + +static void error_callback(int code, const char *description); +static void resize_callback(GLFWwindow *w, int width, int height); +static void focus_callback(GLFWwindow *w, int focus); + +static int create_window(lua_State *L); + +static int window_get_size(lua_State *L); +static int window_set_size(lua_State *L); +static int window_set_resize_callback(lua_State *L); +static int window_unset_resize_callback(lua_State *L); + + +void setup_window(lua_State *L, int tbl_index) { - return false; + /* initialize window struct */ + window.created = false; + window.L = L; + + /* set error handler */ + glfwSetErrorCallback(error_callback); + + /* create window table */ + hs_create_table + (L, + hs_str_cfunc("createWindow", create_window), + hs_str_cfunc("getSize", window_get_size), + hs_str_cfunc("setSize", window_set_size), + hs_str_cfunc("setResizeCallback", window_set_resize_callback), + hs_str_cfunc("unsetResizeCallback", window_unset_resize_callback) + ); + + /* set honey table entry */ + lua_setfield(L, tbl_index, "window"); +} + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * glfw callbacks + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +static void error_callback(int code, const char *description) +{ + honey_error("GLFW error %d: %s", code, description); + hs_throw_error(window.L, "(GLFW error %d) %s", code, description); +} + + +static void resize_callback(GLFWwindow *w, int width, int height) +{ + lua_State *L = window.L; + + if (resize_callback_ref == LUA_NOREF) + /* no resize callback set */ + return; + + /* push callback function */ + hs_rload(L, resize_callback_ref); + + lua_pushinteger(L, width); + lua_pushinteger(L, height); + + if (resize_data_ref == LUA_NOREF || resize_data_ref == LUA_REFNIL) + lua_pushnil(L); + else + hs_rload(L, resize_data_ref); + + hs_call(L, 3, 0); +} + + +static void focus_callback(GLFWwindow *w, int focus) +{ + lua_State *L = window.L; + + if (focus_callback_ref == LUA_NOREF) + /* no focus callback set */ + return; + + /* push callback function */ + hs_rload(L, focus_callback_ref); + + lua_pushboolean(L, focus); + + if (focus_data_ref == LUA_NOREF || focus_data_ref == LUA_REFNIL) + lua_pushnil(L); + else + hs_rload(L, focus_data_ref); + + hs_call(L, 2, 0); +} + + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * window + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +static int create_window(lua_State *L) +{ + /* return immediately if already called */ + if (window.created) return 0; + + lua_Integer x, y; + hs_parse_args(L, hs_int(x), hs_int(y)); + + if (!glfwInit()) { + /* window creation failed :c */ + honey_fatal("failed to create window!"); + hs_throw_error(L, "failed to create window!"); + } + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + window.window = glfwCreateWindow(x, y, "honey", NULL, NULL); + glfwMakeContextCurrent(window.window); + + if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) { + honey_fatal("failed to initialize GLAD"); + glfwTerminate(); + hs_throw_error(L, "failed to initialize GLAD"); + } + + /* bind resize/focus callbacks */ + glfwSetWindowSizeCallback(window.window, resize_callback); + glfwSetWindowFocusCallback(window.window, focus_callback); +} + + +static int window_get_size(lua_State *L) +{ + int width, height; + glfwGetWindowSize(window.window, &width, &height); + lua_pushinteger(L, width); + lua_pushinteger(L, height); + return 2; +} + + +static int window_set_size(lua_State *L) +{ + lua_Integer width, height; + hs_parse_args(L, hs_int(width), hs_int(height)); + glfwSetWindowSize(window.window, width, height); + return 0; +} + + +static int window_set_resize_callback(lua_State *L) +{ + int cb, data; + hs_parse_args(L, hs_func(cb), hs_any(data)); + + lua_pushvalue(L, cb); + resize_callback_ref = hs_rstore(L); + + lua_pushvalue(L, data); + resize_data_ref = hs_rstore(L); + + return 0; +} + + +static int window_unset_resize_callback(lua_State *L) +{ + if (resize_callback_ref != LUA_NOREF) + hs_rdel(L, resize_callback_ref); + if (resize_data_ref != LUA_NOREF) + hs_rdel(L, resize_callback_ref); + + resize_callback_ref = LUA_NOREF; + resize_data_ref = LUA_NOREF; + + return 0; } diff --git a/src/gl/honey_gl.h b/src/gl/honey_gl.h index fc57037..8d5cdd9 100644 --- a/src/gl/honey_gl.h +++ b/src/gl/honey_gl.h @@ -1,18 +1,17 @@ #ifndef HONEY_GL_H #define HONEY_GL_H -#include - -#ifdef UNIT_TEST -#include "test/mock/mock_GLFW.h" -#else #include "glad/glad.h" #include -#endif -extern int honey_gl_window_ref; +struct honey_window { + GLFWwindow * window; + bool created; + lua_State *L; +}; -bool honey_gl_setup(); +extern struct honey_window window; +void setup_window(lua_State *L, int tbl_index); #endif -- cgit v1.2.1