From 253f1d1ca8b4b81f206e4aeb20afe440a6dae8be Mon Sep 17 00:00:00 2001 From: sanine Date: Thu, 18 Aug 2022 22:03:13 -0500 Subject: add glfwInit and glfwTerminate bindings --- src/gl/window.c | 93 +---------- src/gl/window.test.c | 446 +++++++-------------------------------------------- 2 files changed, 66 insertions(+), 473 deletions(-) (limited to 'src/gl') diff --git a/src/gl/window.c b/src/gl/window.c index e16b330..bc654f9 100644 --- a/src/gl/window.c +++ b/src/gl/window.c @@ -3,102 +3,17 @@ #include #include -/* build a table of all possible window hints */ -void create_glfw_window_hints_table(lua_State *L) -{ - /* hint keys */ - hs_create_table(L, - /* window hints */ - hs_str_int("resizable", GLFW_RESIZABLE), - hs_str_int("visible", GLFW_VISIBLE), - hs_str_int("decorated", GLFW_DECORATED), - hs_str_int("focused", GLFW_FOCUSED), - hs_str_int("autoIconify", GLFW_AUTO_ICONIFY), - hs_str_int("floating", GLFW_FLOATING), - hs_str_int("maximized", GLFW_MAXIMIZED), - hs_str_int("centerCursor", GLFW_CENTER_CURSOR), - hs_str_int("transparentFramebuffer", GLFW_TRANSPARENT_FRAMEBUFFER), - hs_str_int("focusOnShow", GLFW_FOCUS_ON_SHOW), - hs_str_int("scaleToMonitor", GLFW_SCALE_TO_MONITOR), - - /* framebuffer hints */ - hs_str_int("redBits", GLFW_RED_BITS), - hs_str_int("greenBits", GLFW_GREEN_BITS), - hs_str_int("blueBits", GLFW_BLUE_BITS), - hs_str_int("alphaBits", GLFW_ALPHA_BITS), - hs_str_int("depthBits", GLFW_DEPTH_BITS), - hs_str_int("stereoscopic", GLFW_STEREO), - hs_str_int("samples", GLFW_SAMPLES), - hs_str_int("srgbCapable", GLFW_SRGB_CAPABLE), - hs_str_int("doubleBuffer", GLFW_DOUBLEBUFFER), - - /* monitor & context hints */ - hs_str_int("refreshRate", GLFW_REFRESH_RATE), - hs_str_int("clientApi", GLFW_CLIENT_API), - hs_str_int("contextCreationApi", GLFW_CONTEXT_CREATION_API), - hs_str_int("contextVersionMajor", GLFW_CONTEXT_VERSION_MAJOR), - hs_str_int("contextVersionMinor", GLFW_CONTEXT_VERSION_MINOR), - hs_str_int("forwardCompatible", GLFW_OPENGL_FORWARD_COMPAT), - hs_str_int("debugContext", GLFW_OPENGL_DEBUG_CONTEXT), - hs_str_int("profile", GLFW_OPENGL_PROFILE), - hs_str_int("contextRobustness", GLFW_CONTEXT_ROBUSTNESS), - hs_str_int("contextReleaseBehavior", GLFW_CONTEXT_RELEASE_BEHAVIOR), - hs_str_int("noError", GLFW_CONTEXT_NO_ERROR) - ); - - /* special hint values */ - hs_create_table(L, - hs_str_int("dontCare", GLFW_DONT_CARE), - - /* client api */ - hs_str_int("glApi", GLFW_OPENGL_API), - hs_str_int("glesApi", GLFW_OPENGL_ES_API), - hs_str_int("noApi", GLFW_NO_API), - - /* context api */ - hs_str_int("nativeApi", GLFW_NATIVE_CONTEXT_API), - hs_str_int("eglApi", GLFW_EGL_CONTEXT_API), - hs_str_int("osMesaApi", GLFW_OSMESA_CONTEXT_API), - - /* robustness */ - hs_str_int("noRobustness", GLFW_NO_ROBUSTNESS), - hs_str_int("noResetNotification", GLFW_NO_RESET_NOTIFICATION), - hs_str_int("loseContextOnReset", GLFW_LOSE_CONTEXT_ON_RESET), - - /* context release */ - hs_str_int("anyBehavior", GLFW_ANY_RELEASE_BEHAVIOR), - hs_str_int("flush", GLFW_RELEASE_BEHAVIOR_FLUSH), - hs_str_int("none", GLFW_RELEASE_BEHAVIOR_NONE), - - /* profile */ - hs_str_int("anyProfile", GLFW_OPENGL_ANY_PROFILE), - hs_str_int("compatabilityProfile", GLFW_OPENGL_COMPAT_PROFILE), - hs_str_int("coreProfile", GLFW_OPENGL_CORE_PROFILE) - ); -} - - int gl_init(lua_State *L) { - if (glfwInit() != GLFW_TRUE) { + if (!glfwInit()) { hs_throw_error(L, "failed to initialize GLFW"); } return 0; } -lua_Integer tointeger(lua_State *L, int index) +int gl_terminate(lua_State *L) { - if (lua_isboolean(L, index)) { - return lua_toboolean(L, index); - } - else if (lua_isnumber(L, index)) { - return lua_tointeger(L, index); - } - else { - hs_throw_error(L, - "expected boolean or number; got %s instead", - lua_typename(L, lua_type(L, index)) - ); - } + glfwTerminate(); + return 0; } diff --git a/src/gl/window.test.c b/src/gl/window.test.c index 6b8e091..b4fb5d4 100644 --- a/src/gl/window.test.c +++ b/src/gl/window.test.c @@ -4,433 +4,111 @@ #include #include "test/honey-test.h" -int mock_glfwInit(); -int mock_hs_throw_error(lua_State *L, const char *format_string, ...); -#define glfwInit mock_glfwInit -#define hs_throw_error mock_hs_throw_error + +int mock_glfwInit_(void); +int mock_hs_throw_error_(lua_State *L, const char *str); +void mock_glfwTerminate_(); + +#define glfwInit mock_glfwInit_ +#define hs_throw_error mock_hs_throw_error_ +#define glfwTerminate mock_glfwTerminate_ #include "gl/window.c" -#undef glfwInit +#undef glfwTerminate #undef hs_throw_error +#undef glfwInit -lily_mock_t *mock_glfwInit_data = NULL; -int mock_glfwInit() +lily_mock_t *mock_glfwInit = NULL; +int mock_glfwInit_() { - lily_mock_call(mock_glfwInit_data, NULL); + struct lily_mock_arg_t args[] = {}; + lily_mock_store_call(mock_glfwInit, args); int result; - mock_dequeue(mock_glfwInit, int, &result); + lily_get_value(mock_glfwInit, int, &result); return result; } -lily_mock_t *mock_hs_throw_error_data = NULL; -int mock_hs_throw_error(lua_State *L, const char *format_string, ...) -{ - /* to avoid basically just re-implementing printf parsing here, - i am limiting this function to be able to receive strings only */ - - /* count format specifiers */ - char *ptr = strchr(format_string, '%'); - int n_args = 0; - while (ptr != NULL) { - n_args += 1; - ptr = strchr(ptr+1, '%'); - } - /* store arguments */ +lily_mock_t *mock_hs_throw_error = NULL; +int mock_hs_throw_error_(lua_State *L, const char *str) +{ struct lily_mock_arg_t args[] = { - { sizeof(const char*), &format_string }, - { sizeof(int), &n_args }, + { sizeof(const char *), &str } }; - lily_mock_call(mock_hs_throw_error_data, args); + lily_mock_store_call(mock_hs_throw_error, args); - /* store format arguments */ - va_list vl; - va_start(vl, format_string); - for (int i=0; in_calls, 1); - lily_assert_int_equal(mock_hs_throw_error_data->n_calls, 0); -} - - -void gl_init_fail_glfwInit() -{ - USE_MOCK(mock_glfwInit); - USE_MOCK(mock_hs_throw_error); - - /* queue failure */ - mock_enqueue(mock_glfwInit, int, GLFW_FALSE); - gl_init(NULL); - - lily_assert_int_equal(mock_glfwInit_data->n_calls, 1); - lily_assert_int_equal(mock_hs_throw_error_data->n_calls, 1); - - const char *fmt; int argc; - struct lily_mock_arg_t args[] = { - { sizeof(const char*), &fmt }, - { sizeof(int), &argc }, - }; - lily_get_call(mock_hs_throw_error_data, args, 0); + lua_State *L = luaL_newstate(); + lily_store_value(mock_glfwInit, int, 1); + lua_pushcfunction(L, gl_init); + int err = lua_pcall(L, 0, 0, 0); + lua_close(L); - lily_assert_string_equal((char*) fmt, "failed to initialize GLFW"); + lily_assert_int_equal(err, 0); + lily_assert_int_equal(mock_glfwInit->n_calls, 1); + lily_assert_int_equal(mock_hs_throw_error->n_calls, 0); } -int get_int(lua_State *L, int table_index, const char *key) +void gl_init_fails() { - lua_getfield(L, table_index, key); - lily_assert_msg(lua_isnumber(L, -1), LILY_LOCATION, "key %s is not a number", key); - int n = lua_tointeger(L, -1); - lua_pop(L, 1); - return n; -} - -#define CHECK_VALUE(str, num) \ - do { \ - int value = get_int(L, 1, str); \ - lily_assert_int_equal(value, num); \ - } while(0) + lily_mock_use(&mock_glfwInit); + lily_mock_use(&mock_hs_throw_error); -void glfw_window_hints_table() -{ lua_State *L = luaL_newstate(); - - lily_assert_int_equal(lua_gettop(L), 0); - create_glfw_window_hints_table(L); - lily_assert_int_equal(lua_gettop(L), 2); - lily_assert_true(lua_istable(L, 1)); - - /* window hints */ - lily_assert_int_equal( - get_int(L, 1, "resizable"), - GLFW_RESIZABLE - ); - - lily_assert_int_equal( - get_int(L, 1, "visible"), - GLFW_VISIBLE - ); - - lily_assert_int_equal( - get_int(L, 1, "decorated"), - GLFW_DECORATED - ); - - lily_assert_int_equal( - get_int(L, 1, "focused"), - GLFW_FOCUSED - ); - - lily_assert_int_equal( - get_int(L, 1, "autoIconify"), - GLFW_AUTO_ICONIFY - ); - - lily_assert_int_equal( - get_int(L, 1, "floating"), - GLFW_FLOATING - ); - - lily_assert_int_equal( - get_int(L, 1, "maximized"), - GLFW_MAXIMIZED - ); - - lily_assert_int_equal( - get_int(L, 1, "centerCursor"), - GLFW_CENTER_CURSOR - ); - - lily_assert_int_equal( - get_int(L, 1, "transparentFramebuffer"), - GLFW_TRANSPARENT_FRAMEBUFFER - ); - - lily_assert_int_equal( - get_int(L, 1, "focusOnShow"), - GLFW_FOCUS_ON_SHOW - ); - - lily_assert_int_equal( - get_int(L, 1, "scaleToMonitor"), - GLFW_SCALE_TO_MONITOR - ); - - - /* framebuffer hints */ - /* (don't expose accumulation or auxiliary buffer hints) */ - lily_assert_int_equal( - get_int(L, 1, "redBits"), - GLFW_RED_BITS - ); - - lily_assert_int_equal( - get_int(L, 1, "greenBits"), - GLFW_GREEN_BITS - ); - - lily_assert_int_equal( - get_int(L, 1, "blueBits"), - GLFW_BLUE_BITS - ); - - lily_assert_int_equal( - get_int(L, 1, "alphaBits"), - GLFW_ALPHA_BITS - ); - - lily_assert_int_equal( - get_int(L, 1, "depthBits"), - GLFW_DEPTH_BITS - ); - - lily_assert_int_equal( - get_int(L, 1, "stereoscopic"), - GLFW_STEREO - ); - - lily_assert_int_equal( - get_int(L, 1, "samples"), - GLFW_SAMPLES - ); - - lily_assert_int_equal( - get_int(L, 1, "srgbCapable"), - GLFW_SRGB_CAPABLE - ); - - lily_assert_int_equal( - get_int(L, 1, "doubleBuffer"), - GLFW_DOUBLEBUFFER - ); - - - /* monitor & context hints */ - lily_assert_int_equal( - get_int(L, 1, "refreshRate"), - GLFW_REFRESH_RATE - ); - - lily_assert_int_equal( - get_int(L, 1, "clientApi"), - GLFW_CLIENT_API - ); - - lily_assert_int_equal( - get_int(L, 1, "contextCreationApi"), - GLFW_CONTEXT_CREATION_API - ); - - lily_assert_int_equal( - get_int(L, 1, "contextVersionMajor"), - GLFW_CONTEXT_VERSION_MAJOR - ); - - lily_assert_int_equal( - get_int(L, 1, "contextVersionMinor"), - GLFW_CONTEXT_VERSION_MINOR - ); - - lily_assert_int_equal( - get_int(L, 1, "forwardCompatible"), - GLFW_OPENGL_FORWARD_COMPAT - ); - - lily_assert_int_equal( - get_int(L, 1, "debugContext"), - GLFW_OPENGL_DEBUG_CONTEXT - ); - - lily_assert_int_equal( - get_int(L, 1, "profile"), - GLFW_OPENGL_PROFILE - ); - - lily_assert_int_equal( - get_int(L, 1, "contextRobustness"), - GLFW_CONTEXT_ROBUSTNESS - ); - - lily_assert_int_equal( - get_int(L, 1, "contextReleaseBehavior"), - GLFW_CONTEXT_RELEASE_BEHAVIOR - ); - - lily_assert_int_equal( - get_int(L, 1, "noError"), - GLFW_CONTEXT_NO_ERROR - ); - - - /* special hint values */ - - lily_assert_int_equal( - get_int(L, 2, "dontCare"), - GLFW_DONT_CARE - ); - - /* client api */ - lily_assert_int_equal( - get_int(L, 2, "glApi"), - GLFW_OPENGL_API - ); - - lily_assert_int_equal( - get_int(L, 2, "glesApi"), - GLFW_OPENGL_ES_API - ); - - lily_assert_int_equal( - get_int(L, 2, "noApi"), - GLFW_NO_API - ); - - /* context api */ - lily_assert_int_equal( - get_int(L, 2, "nativeApi"), - GLFW_NATIVE_CONTEXT_API - ); - - lily_assert_int_equal( - get_int(L, 2, "eglApi"), - GLFW_EGL_CONTEXT_API - ); - - lily_assert_int_equal( - get_int(L, 2, "osMesaApi"), - GLFW_OSMESA_CONTEXT_API - ); - - /* robustness */ - lily_assert_int_equal( - get_int(L, 2, "noRobustness"), - GLFW_NO_ROBUSTNESS - ); - - lily_assert_int_equal( - get_int(L, 2, "noResetNotification"), - GLFW_NO_RESET_NOTIFICATION - ); - - lily_assert_int_equal( - get_int(L, 2, "loseContextOnReset"), - GLFW_LOSE_CONTEXT_ON_RESET - ); - - /* release */ - lily_assert_int_equal( - get_int(L, 2, "anyBehavior"), - GLFW_ANY_RELEASE_BEHAVIOR - ); - - lily_assert_int_equal( - get_int(L, 2, "flush"), - GLFW_RELEASE_BEHAVIOR_FLUSH - ); - - lily_assert_int_equal( - get_int(L, 2, "none"), - GLFW_RELEASE_BEHAVIOR_NONE - ); - - /* profile */ - lily_assert_int_equal( - get_int(L, 2, "anyProfile"), - GLFW_OPENGL_ANY_PROFILE - ); - - lily_assert_int_equal( - get_int(L, 2, "compatabilityProfile"), - GLFW_OPENGL_COMPAT_PROFILE - ); - - lily_assert_int_equal( - get_int(L, 2, "coreProfile"), - GLFW_OPENGL_CORE_PROFILE - ); - + lily_store_value(mock_glfwInit, int, 0); + lua_pushcfunction(L, gl_init); + int err = lua_pcall(L, 0, 0, 0); lua_close(L); -} - -void tointeger_parses_bool() -{ - USE_MOCK(mock_hs_throw_error); - lua_State *L = luaL_newstate(); - - lua_pushboolean(L, 0); - lily_assert_false(lua_toboolean(L, -1)); - lily_assert_int_equal(tointeger(L, -1), 0); - - lua_pushboolean(L, 1); - lily_assert_true(lua_toboolean(L, -1)); - lily_assert_int_equal(tointeger(L, -1), 1); - - lua_close(L); + lily_assert_int_equal(err, LUA_ERRRUN); + lily_assert_int_equal(mock_hs_throw_error->n_calls, 1); } -void tointeger_parses_int() +void gl_terminate_works() { - USE_MOCK(mock_hs_throw_error); - lua_State *L = luaL_newstate(); - - lua_pushinteger(L, 234); - lua_pushinteger(L, 55555); - - lily_assert_int_equal(tointeger(L, -2), 234); - lily_assert_int_equal(tointeger(L, -1), 55555); + lily_mock_use(&mock_glfwTerminate); + lua_State *L = luaL_newstate(); + lua_pushcfunction(L, gl_terminate); + int err = lua_pcall(L, 0, 0, 0); lua_close(L); + + lily_assert_int_equal(err, 0); + lily_assert_int_equal(mock_glfwTerminate->n_calls, 1); } -void tointeger_fails_other() +void suite_window() { - USE_MOCK(mock_hs_throw_error); - lua_State *L = luaL_newstate(); + lily_run_test(gl_init_succeeds); + lily_run_test(gl_init_fails); + lily_run_test(gl_terminate_works); - lua_pushstring(L, "hey there babe"); - tointeger(L, -1); - lily_assert_int_equal(mock_hs_throw_error_data->n_calls, 1); + lily_mock_destroy(mock_glfwInit); + lily_mock_destroy(mock_hs_throw_error); + lily_mock_destroy(mock_glfwTerminate); } -- cgit v1.2.1 From 275536b36657744d802866c060654e2b5cd5a5f8 Mon Sep 17 00:00:00 2001 From: sanine Date: Thu, 18 Aug 2022 22:46:40 -0500 Subject: implement working windows --- src/gl/gl.c | 34 +++++++++++++++ src/gl/gl.h | 9 ++++ src/gl/gl.test.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/gl/window.c | 56 ++++++++++++++++++++++--- src/gl/window.test.c | 114 --------------------------------------------------- 5 files changed, 207 insertions(+), 120 deletions(-) create mode 100644 src/gl/gl.c create mode 100644 src/gl/gl.h create mode 100644 src/gl/gl.test.c delete mode 100644 src/gl/window.test.c (limited to 'src/gl') diff --git a/src/gl/gl.c b/src/gl/gl.c new file mode 100644 index 0000000..8613e70 --- /dev/null +++ b/src/gl/gl.c @@ -0,0 +1,34 @@ +#include "gl/glad/glad.h" +#include +#include +#include + + +int gl_init(lua_State *L); +int gl_terminate(lua_State *L); + + +void setup_gl(lua_State *L, int honey_index) +{ + hs_create_table(L, + hs_str_cfunc("init", gl_init), + hs_str_cfunc("terminate", gl_terminate) + ); + lua_setfield(L, honey_index, "gl"); +} + + +int gl_init(lua_State *L) +{ + if (!glfwInit()) { + hs_throw_error(L, "failed to initialize GLFW"); + } + return 0; +} + + +int gl_terminate(lua_State *L) +{ + glfwTerminate(); + return 0; +} diff --git a/src/gl/gl.h b/src/gl/gl.h new file mode 100644 index 0000000..2e27851 --- /dev/null +++ b/src/gl/gl.h @@ -0,0 +1,9 @@ +#ifndef HONEY_GL_H +#define HONEY_GL_H + +#include + +void setup_gl(lua_State *L, int honey_index); +void setup_window(lua_State *L, int honey_index); + +#endif diff --git a/src/gl/gl.test.c b/src/gl/gl.test.c new file mode 100644 index 0000000..9bacbf9 --- /dev/null +++ b/src/gl/gl.test.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include "test/honey-test.h" + + +int mock_glfwInit_(void); +int mock_hs_throw_error_(lua_State *L, const char *str); +void mock_glfwTerminate_(); + +#define glfwInit mock_glfwInit_ +#define hs_throw_error mock_hs_throw_error_ +#define glfwTerminate mock_glfwTerminate_ +#include "gl/gl.c" +#undef glfwTerminate +#undef hs_throw_error +#undef glfwInit + + +lily_mock_t *mock_glfwInit = NULL; +int mock_glfwInit_() +{ + struct lily_mock_arg_t args[] = {}; + lily_mock_store_call(mock_glfwInit, args); + + int result; + lily_get_value(mock_glfwInit, int, &result); + return result; +} + + +lily_mock_t *mock_hs_throw_error = NULL; +int mock_hs_throw_error_(lua_State *L, const char *str) +{ + struct lily_mock_arg_t args[] = { + { sizeof(const char *), &str } + }; + lily_mock_store_call(mock_hs_throw_error, args); + + lua_pushstring(L, "some error"); + lua_error(L); + + return 0; +} + + +lily_mock_t *mock_glfwTerminate = NULL; +void mock_glfwTerminate_() +{ + struct lily_mock_arg_t args[] = {}; + lily_mock_store_call(mock_glfwTerminate, args); +} + + +/* ~~~~~~~~ suite ~~~~~~~~ */ + +void gl_init_succeeds() +{ + lily_mock_use(&mock_glfwInit); + lily_mock_use(&mock_hs_throw_error); + + lua_State *L = luaL_newstate(); + lily_store_value(mock_glfwInit, int, 1); + lua_pushcfunction(L, gl_init); + int err = lua_pcall(L, 0, 0, 0); + lua_close(L); + + lily_assert_int_equal(err, 0); + lily_assert_int_equal(mock_glfwInit->n_calls, 1); + lily_assert_int_equal(mock_hs_throw_error->n_calls, 0); +} + + +void gl_init_fails() +{ + lily_mock_use(&mock_glfwInit); + lily_mock_use(&mock_hs_throw_error); + + lua_State *L = luaL_newstate(); + lily_store_value(mock_glfwInit, int, 0); + lua_pushcfunction(L, gl_init); + int err = lua_pcall(L, 0, 0, 0); + lua_close(L); + + lily_assert_int_equal(err, LUA_ERRRUN); + lily_assert_int_equal(mock_hs_throw_error->n_calls, 1); +} + + +void gl_terminate_works() +{ + lily_mock_use(&mock_glfwTerminate); + + lua_State *L = luaL_newstate(); + lua_pushcfunction(L, gl_terminate); + int err = lua_pcall(L, 0, 0, 0); + lua_close(L); + + lily_assert_int_equal(err, 0); + lily_assert_int_equal(mock_glfwTerminate->n_calls, 1); +} + + +void suite_gl() +{ + lily_run_test(gl_init_succeeds); + lily_run_test(gl_init_fails); + lily_run_test(gl_terminate_works); + + lily_mock_destroy(mock_glfwInit); + lily_mock_destroy(mock_hs_throw_error); + lily_mock_destroy(mock_glfwTerminate); +} diff --git a/src/gl/window.c b/src/gl/window.c index bc654f9..8434a5a 100644 --- a/src/gl/window.c +++ b/src/gl/window.c @@ -3,17 +3,61 @@ #include #include -int gl_init(lua_State *L) + +int window_create(lua_State *L); +int window_destroy(lua_State *L); +int window_should_close(lua_State *L); +int window_poll_events(lua_State *L); + + +void setup_window(lua_State *L, int honey_index) +{ + hs_create_table(L, + hs_str_cfunc("create", window_create), + hs_str_cfunc("destroy", window_destroy), + hs_str_cfunc("shouldClose", window_should_close), + hs_str_cfunc("pollEvents", window_poll_events) + ); + lua_setfield(L, honey_index, "window"); +} + + +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"); + lua_pushlightuserdata(L, win); + return 1; +} + + +int window_destroy(lua_State *L) { - if (!glfwInit()) { - hs_throw_error(L, "failed to initialize GLFW"); - } + void *ptr; + hs_parse_args(L, hs_light(ptr)); + GLFWwindow *win = ptr; + glfwDestroyWindow(win); return 0; } -int gl_terminate(lua_State *L) +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) { - glfwTerminate(); + glfwPollEvents(); return 0; } diff --git a/src/gl/window.test.c b/src/gl/window.test.c deleted file mode 100644 index b4fb5d4..0000000 --- a/src/gl/window.test.c +++ /dev/null @@ -1,114 +0,0 @@ -#include -#include -#include -#include -#include "test/honey-test.h" - - -int mock_glfwInit_(void); -int mock_hs_throw_error_(lua_State *L, const char *str); -void mock_glfwTerminate_(); - -#define glfwInit mock_glfwInit_ -#define hs_throw_error mock_hs_throw_error_ -#define glfwTerminate mock_glfwTerminate_ -#include "gl/window.c" -#undef glfwTerminate -#undef hs_throw_error -#undef glfwInit - - -lily_mock_t *mock_glfwInit = NULL; -int mock_glfwInit_() -{ - struct lily_mock_arg_t args[] = {}; - lily_mock_store_call(mock_glfwInit, args); - - int result; - lily_get_value(mock_glfwInit, int, &result); - return result; -} - - -lily_mock_t *mock_hs_throw_error = NULL; -int mock_hs_throw_error_(lua_State *L, const char *str) -{ - struct lily_mock_arg_t args[] = { - { sizeof(const char *), &str } - }; - lily_mock_store_call(mock_hs_throw_error, args); - - lua_pushstring(L, "some error"); - lua_error(L); - - return 0; -} - - -lily_mock_t *mock_glfwTerminate = NULL; -void mock_glfwTerminate_() -{ - struct lily_mock_arg_t args[] = {}; - lily_mock_store_call(mock_glfwTerminate, args); -} - - -/* ~~~~~~~~ suite ~~~~~~~~ */ - -void gl_init_succeeds() -{ - lily_mock_use(&mock_glfwInit); - lily_mock_use(&mock_hs_throw_error); - - lua_State *L = luaL_newstate(); - lily_store_value(mock_glfwInit, int, 1); - lua_pushcfunction(L, gl_init); - int err = lua_pcall(L, 0, 0, 0); - lua_close(L); - - lily_assert_int_equal(err, 0); - lily_assert_int_equal(mock_glfwInit->n_calls, 1); - lily_assert_int_equal(mock_hs_throw_error->n_calls, 0); -} - - -void gl_init_fails() -{ - lily_mock_use(&mock_glfwInit); - lily_mock_use(&mock_hs_throw_error); - - lua_State *L = luaL_newstate(); - lily_store_value(mock_glfwInit, int, 0); - lua_pushcfunction(L, gl_init); - int err = lua_pcall(L, 0, 0, 0); - lua_close(L); - - lily_assert_int_equal(err, LUA_ERRRUN); - lily_assert_int_equal(mock_hs_throw_error->n_calls, 1); -} - - -void gl_terminate_works() -{ - lily_mock_use(&mock_glfwTerminate); - - lua_State *L = luaL_newstate(); - lua_pushcfunction(L, gl_terminate); - int err = lua_pcall(L, 0, 0, 0); - lua_close(L); - - lily_assert_int_equal(err, 0); - lily_assert_int_equal(mock_glfwTerminate->n_calls, 1); -} - - -void suite_window() -{ - lily_run_test(gl_init_succeeds); - lily_run_test(gl_init_fails); - lily_run_test(gl_terminate_works); - - lily_mock_destroy(mock_glfwInit); - lily_mock_destroy(mock_hs_throw_error); - lily_mock_destroy(mock_glfwTerminate); -} -- cgit v1.2.1 From ecde0c8110da1c1f94cce7f6a1fa9406d04eca69 Mon Sep 17 00:00:00 2001 From: sanine Date: Fri, 19 Aug 2022 00:39:04 -0500 Subject: add several buffer-related functions --- src/gl/gl.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/gl/gl.test.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 130 insertions(+), 3 deletions(-) (limited to 'src/gl') diff --git a/src/gl/gl.c b/src/gl/gl.c index 8613e70..7b07027 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -1,18 +1,36 @@ +#include #include "gl/glad/glad.h" #include #include #include +/* needs to be here because glad uses macros to define glBufferData */ +#ifdef HONEY_TEST_H +#undef glBufferData +#define glBufferData mock_glBufferData_ +#endif + int gl_init(lua_State *L); int gl_terminate(lua_State *L); +int gl_create_buffer(lua_State *L); +int gl_bind_buffer(lua_State *L); +int gl_buffer_data(lua_State *L); void setup_gl(lua_State *L, int honey_index) { + int buffer_binding_targets = hs_create_table(L, + hs_str_int("arrayBuffer", GL_ARRAY_BUFFER), + ); + hs_create_table(L, hs_str_cfunc("init", gl_init), - hs_str_cfunc("terminate", gl_terminate) + hs_str_cfunc("terminate", gl_terminate), + hs_str_cfunc("createBuffer", gl_create_buffer), + hs_str_cfunc("bindBuffer", gl_bind_buffer), + hs_str_tbl("bufferTarget", buffer_binding_targets), + hs_str_cfunc("bufferData", gl_buffer_data), ); lua_setfield(L, honey_index, "gl"); } @@ -32,3 +50,48 @@ int gl_terminate(lua_State *L) glfwTerminate(); return 0; } + + +int gl_create_buffer(lua_State *L) +{ + int buf; + glGenBuffers(1, &buf); + lua_pushinteger(L, buf); + return 1; +} + + +int gl_bind_buffer(lua_State *L) +{ + lua_Integer buf, target; + hs_parse_args(L, hs_int(buf), hs_int(target)); + glBindBuffer(buf, target); + return 0; +} + + +int gl_buffer_data(lua_State *L) +{ + lua_Integer target, usage; + int table; + hs_parse_args(L, hs_int(target), hs_tbl(table), hs_int(usage)); + + /* build raw buffer */ + size_t len = lua_objlen(L, table); + lua_Number *buf = malloc(len * sizeof(lua_Number)); + if (buf == NULL) + hs_throw_error(L, "failed to allocate intermediary buffer"); + for (int i=0; in_calls, 1); + int target; size_t size; int usage; + struct lily_mock_arg_t args[] = { + { sizeof(int), &target }, + { sizeof(size_t), &size }, + { sizeof(int), &usage } + }; + lily_mock_get_call(mock_glBufferData, args, 0); + lily_assert_int_equal(target, GL_ARRAY_BUFFER); + lily_assert_int_equal(size, 3*sizeof(lua_Number)); + lily_assert_int_equal(usage, GL_STATIC_DRAW); + + lua_Number n; + lily_get_value(mock_glBufferData, lua_Number, &n); + lily_assert_float_equal(n, 22, 0.1); + lily_get_value(mock_glBufferData, lua_Number, &n); + lily_assert_float_equal(n, 33, 0.1); + lily_get_value(mock_glBufferData, lua_Number, &n); + lily_assert_float_equal(n, 44, 0.1); +} + + void suite_gl() { lily_run_test(gl_init_succeeds); lily_run_test(gl_init_fails); lily_run_test(gl_terminate_works); + lily_run_test(gl_buffer_data_works); lily_mock_destroy(mock_glfwInit); lily_mock_destroy(mock_hs_throw_error); lily_mock_destroy(mock_glfwTerminate); + lily_mock_destroy(mock_glBufferData); } -- cgit v1.2.1 From 899e70147ff7c866f131ba7bfb98193c4e68027f Mon Sep 17 00:00:00 2001 From: sanine Date: Fri, 19 Aug 2022 13:53:18 -0500 Subject: add shaders and basic drawing functions --- src/gl/gl.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/gl/window.c | 26 ++++++- 2 files changed, 253 insertions(+), 2 deletions(-) (limited to 'src/gl') diff --git a/src/gl/gl.c b/src/gl/gl.c index 7b07027..7364b1c 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -1,4 +1,5 @@ #include +#include #include "gl/glad/glad.h" #include #include @@ -12,11 +13,34 @@ int gl_init(lua_State *L); +int glad_init(lua_State *L); int gl_terminate(lua_State *L); + +/* buffers */ int gl_create_buffer(lua_State *L); int gl_bind_buffer(lua_State *L); int gl_buffer_data(lua_State *L); +int gl_vertex_array_create(lua_State *L); +int gl_vertex_array_bind(lua_State *L); +int gl_vertex_attrib_pointer(lua_State *L); + +/* shaders */ +int gl_create_shader(lua_State *L); +int gl_shader_set_source(lua_State *L); +int gl_shader_compile(lua_State *L); +int gl_shader_delete(lua_State *L); + +int gl_program_create(lua_State *L); +int gl_program_attach_shader(lua_State *L); +int gl_program_link(lua_State *L); +int gl_program_use(lua_State *L); + +/* drawing */ +int gl_draw_arrays(lua_State *L); +int gl_set_clear_color(lua_State *L); +int gl_clear(lua_State *L); + void setup_gl(lua_State *L, int honey_index) { @@ -24,13 +48,66 @@ void setup_gl(lua_State *L, int honey_index) hs_str_int("arrayBuffer", GL_ARRAY_BUFFER), ); + int buffer_usage_patterns = hs_create_table(L, + hs_str_int("streamDraw", GL_STREAM_DRAW), + hs_str_int("staticDraw", GL_STATIC_DRAW), + hs_str_int("dynamicDraw", GL_DYNAMIC_DRAW), + ); + + int shader_types = hs_create_table(L, + hs_str_int("vertexShader", GL_VERTEX_SHADER), + hs_str_int("fragmentShader", GL_FRAGMENT_SHADER), + ); + + int primitive_types = hs_create_table(L, + hs_str_int("points", GL_POINTS), + hs_str_int("lines", GL_LINES), + hs_str_int("triangles", GL_TRIANGLES), + ); + + int buffer_masks = hs_create_table(L, + hs_str_int("colorBuffer", GL_COLOR_BUFFER_BIT), + hs_str_int("depthBuffer", GL_DEPTH_BUFFER_BIT), + hs_str_int("stencilBuffer", GL_STENCIL_BUFFER_BIT), + ); + hs_create_table(L, hs_str_cfunc("init", gl_init), + hs_str_cfunc("initGlad", glad_init), hs_str_cfunc("terminate", gl_terminate), + + /* buffer */ hs_str_cfunc("createBuffer", gl_create_buffer), hs_str_cfunc("bindBuffer", gl_bind_buffer), - hs_str_tbl("bufferTarget", buffer_binding_targets), hs_str_cfunc("bufferData", gl_buffer_data), + + hs_str_cfunc("createVertexArray", gl_vertex_array_create), + hs_str_cfunc("bindVertexArray", gl_vertex_array_bind), + hs_str_cfunc("vertexAttribPointer", gl_vertex_attrib_pointer), + + hs_str_tbl("bufferTarget", buffer_binding_targets), + hs_str_tbl("bufferUsage", buffer_usage_patterns), + + /* shader */ + hs_str_cfunc("createShader", gl_create_shader), + hs_str_cfunc("setShaderSource", gl_shader_set_source), + hs_str_cfunc("compileShader", gl_shader_compile), + hs_str_cfunc("deleteShader", gl_shader_delete), + + hs_str_cfunc("createProgram", gl_program_create), + hs_str_cfunc("programAttachShader", gl_program_attach_shader), + hs_str_cfunc("linkProgram", gl_program_link), + hs_str_cfunc("useProgram", gl_program_use), + + hs_str_tbl("shaderType", shader_types), + + /* drawing */ + hs_str_cfunc("drawArrays", gl_draw_arrays), + hs_str_cfunc("setClearColor", gl_set_clear_color), + hs_str_cfunc("clear", gl_clear), + + hs_str_tbl("primitiveType", primitive_types), + hs_str_tbl("bufferMask", buffer_masks), ); lua_setfield(L, honey_index, "gl"); } @@ -45,6 +122,14 @@ int gl_init(lua_State *L) } +int glad_init(lua_State *L) +{ + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { + hs_throw_error(L, "failed to initialize GLAD"); + } +} + + int gl_terminate(lua_State *L) { glfwTerminate(); @@ -95,3 +180,145 @@ int gl_buffer_data(lua_State *L) free(buf); return 0; } + + +int gl_create_shader(lua_State *L) +{ + lua_Integer type; + hs_parse_args(L, hs_int(type)); + lua_Integer shader = glCreateShader(type); + lua_pushinteger(L, shader); + return 1; +} + + +int gl_shader_set_source(lua_State *L) +{ + lua_Integer shader; + char *code; + hs_parse_args(L, hs_int(shader), hs_str(code)); + glShaderSource(shader, 1, &code, NULL); + return 0; +} + + +int gl_shader_compile(lua_State *L) +{ + lua_Integer shader; + hs_parse_args(L, hs_int(shader)); + glCompileShader(shader); + int success; char log[1024]; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(shader, 1024, NULL, log); + hs_throw_error(L, "shader compilation failed: %s", log); + } + return 0; +} + + +int gl_shader_delete(lua_State *L) +{ + lua_Integer shader; + hs_parse_args(L, hs_int(shader)); + glDeleteShader(shader); + return 0; +} + + +int gl_program_create(lua_State *L) +{ + lua_Integer program = glCreateProgram(); + lua_pushinteger(L, program); + return 1; +} + + +int gl_program_attach_shader(lua_State *L) +{ + lua_Integer program, shader; + hs_parse_args(L, hs_int(program), hs_int(shader)), + glAttachShader(program, shader); + return 0; +} + + +int gl_program_link(lua_State *L) +{ + lua_Integer program; + hs_parse_args(L, hs_int(program)); + glLinkProgram(program); + int success; char log[1024]; + glGetProgramiv(program, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(program, 1024, NULL, log); + hs_throw_error(L, "shader linking failed: %s", log); + } + return 0; +} + + +int gl_program_use(lua_State *L) +{ + lua_Integer program; + hs_parse_args(L, hs_int(program)); + glUseProgram(program); + return 0; +} + + +int gl_vertex_array_create(lua_State *L) +{ + int array; + glGenVertexArrays(1, &array); + lua_pushinteger(L, array); + return 1; +} + + +int gl_vertex_array_bind(lua_State *L) +{ + lua_Integer array; + hs_parse_args(L, hs_int(array)); + glBindVertexArray(array); + return 0; +} + + +int gl_vertex_attrib_pointer(lua_State *L) +{ + lua_Integer index, size, stride, offset; + bool normalized; + hs_parse_args(L, hs_int(index), hs_int(size), hs_bool(normalized), hs_int(stride), hs_int(offset)); + glVertexAttribPointer(index, size, GL_FLOAT, + normalized, stride*sizeof(lua_Number), + (void*) (offset*sizeof(lua_Number))); + return 0; +} + + +int gl_set_clear_color(lua_State *L) +{ + lua_Number r, g, b, a; + hs_parse_args(L, hs_num(r), hs_num(g), hs_num(b), hs_num(a)); + glClearColor(r, g, b, a); + return 0; +} + + +int gl_clear(lua_State *L) +{ + lua_Integer mask; + hs_parse_args(L, hs_int(mask)); + glClear(mask); + return 0; +} + + +int gl_draw_arrays(lua_State *L) +{ + lua_Integer mode, first, count; + hs_parse_args(L, hs_int(mode), hs_int(first), hs_int(count)); + glDrawArrays(mode, first, count); + return 0; +} diff --git a/src/gl/window.c b/src/gl/window.c index 8434a5a..cb30d3f 100644 --- a/src/gl/window.c +++ b/src/gl/window.c @@ -6,8 +6,10 @@ int window_create(lua_State *L); int window_destroy(lua_State *L); +int window_make_context_current(lua_State *L); int window_should_close(lua_State *L); int window_poll_events(lua_State *L); +int window_swap_buffers(lua_State *L); void setup_window(lua_State *L, int honey_index) @@ -15,8 +17,10 @@ void setup_window(lua_State *L, int honey_index) 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("shouldClose", window_should_close), - hs_str_cfunc("pollEvents", window_poll_events) + hs_str_cfunc("pollEvents", window_poll_events), + hs_str_cfunc("swapBuffers", window_swap_buffers), ); lua_setfield(L, honey_index, "window"); } @@ -46,6 +50,16 @@ int window_destroy(lua_State *L) } +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_should_close(lua_State *L) { void *ptr; @@ -61,3 +75,13 @@ 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; +} -- cgit v1.2.1 From b6ccd8b31a78ef99f8c346d9b60f123c7ac813ec Mon Sep 17 00:00:00 2001 From: sanine Date: Fri, 19 Aug 2022 14:48:26 -0500 Subject: enable hello triangle --- src/gl/gl.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src/gl') diff --git a/src/gl/gl.c b/src/gl/gl.c index 7364b1c..485d412 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -24,6 +24,7 @@ int gl_buffer_data(lua_State *L); int gl_vertex_array_create(lua_State *L); int gl_vertex_array_bind(lua_State *L); int gl_vertex_attrib_pointer(lua_State *L); +int gl_vertex_array_enable_attrib(lua_State *L); /* shaders */ int gl_create_shader(lua_State *L); @@ -84,6 +85,7 @@ void setup_gl(lua_State *L, int honey_index) hs_str_cfunc("createVertexArray", gl_vertex_array_create), hs_str_cfunc("bindVertexArray", gl_vertex_array_bind), hs_str_cfunc("vertexAttribPointer", gl_vertex_attrib_pointer), + hs_str_cfunc("vertexArrayEnableAttrib", gl_vertex_array_enable_attrib), hs_str_tbl("bufferTarget", buffer_binding_targets), hs_str_tbl("bufferUsage", buffer_usage_patterns), @@ -163,7 +165,7 @@ int gl_buffer_data(lua_State *L) /* build raw buffer */ size_t len = lua_objlen(L, table); - lua_Number *buf = malloc(len * sizeof(lua_Number)); + float *buf = malloc(len * sizeof(float)); if (buf == NULL) hs_throw_error(L, "failed to allocate intermediary buffer"); for (int i=0; i Date: Sat, 20 Aug 2022 15:37:04 -0500 Subject: fix bug in gl.bufferData and add error checking --- src/gl/gl.c | 47 ++++++++++++++++++++++++++++++---- src/gl/gl.test.c | 16 ++++++------ src/gl/window.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/gl/window.test.c | 24 ++++++++++++++++++ 4 files changed, 146 insertions(+), 13 deletions(-) create mode 100644 src/gl/window.test.c (limited to 'src/gl') diff --git a/src/gl/gl.c b/src/gl/gl.c index 485d412..581cf39 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -15,6 +15,7 @@ int gl_init(lua_State *L); int glad_init(lua_State *L); int gl_terminate(lua_State *L); +int gl_get_error(lua_State *L); /* buffers */ int gl_create_buffer(lua_State *L); @@ -38,6 +39,7 @@ int gl_program_link(lua_State *L); int gl_program_use(lua_State *L); /* drawing */ +int gl_set_viewport(lua_State *L); int gl_draw_arrays(lua_State *L); int gl_set_clear_color(lua_State *L); int gl_clear(lua_State *L); @@ -45,6 +47,15 @@ int gl_clear(lua_State *L); void setup_gl(lua_State *L, int honey_index) { + int error_types = hs_create_table(L, + hs_str_int("noError", GL_NO_ERROR), + hs_str_int("invalidEnum", GL_INVALID_ENUM), + hs_str_int("invalidValue", GL_INVALID_VALUE), + hs_str_int("invalidOperation", GL_INVALID_OPERATION), + hs_str_int("invalidFramebufferOperation", GL_INVALID_FRAMEBUFFER_OPERATION), + hs_str_int("outOfMemory", GL_OUT_OF_MEMORY), + ); + int buffer_binding_targets = hs_create_table(L, hs_str_int("arrayBuffer", GL_ARRAY_BUFFER), ); @@ -76,6 +87,9 @@ void setup_gl(lua_State *L, int honey_index) hs_str_cfunc("init", gl_init), hs_str_cfunc("initGlad", glad_init), hs_str_cfunc("terminate", gl_terminate), + hs_str_cfunc("getError", gl_get_error), + + hs_str_tbl("errorType", error_types), /* buffer */ hs_str_cfunc("createBuffer", gl_create_buffer), @@ -107,6 +121,7 @@ void setup_gl(lua_State *L, int honey_index) hs_str_cfunc("drawArrays", gl_draw_arrays), hs_str_cfunc("setClearColor", gl_set_clear_color), hs_str_cfunc("clear", gl_clear), + hs_str_cfunc("setViewport", gl_set_viewport), hs_str_tbl("primitiveType", primitive_types), hs_str_tbl("bufferMask", buffer_masks), @@ -139,6 +154,13 @@ int gl_terminate(lua_State *L) } +int gl_get_error(lua_State *L) +{ + lua_pushinteger(L, glGetError()); + return 1; +} + + int gl_create_buffer(lua_State *L) { int buf; @@ -150,9 +172,9 @@ int gl_create_buffer(lua_State *L) int gl_bind_buffer(lua_State *L) { - lua_Integer buf, target; - hs_parse_args(L, hs_int(buf), hs_int(target)); - glBindBuffer(buf, target); + lua_Integer target, buf; + hs_parse_args(L, hs_int(target), hs_int(buf)); + glBindBuffer(target, buf); return 0; } @@ -174,9 +196,13 @@ int gl_buffer_data(lua_State *L) hs_throw_error(L, "all table items must be numbers (failed at index %d)", i); } buf[i] = lua_tonumber(L, -1); + printf(" [%d] %f\n", i, buf[i]); lua_pop(L, 1); } + printf("target: %d\n", target); + printf("GL_ARRAY_BUFFER: %d\n", GL_ARRAY_BUFFER); + /* call */ glBufferData(target, len*sizeof(float), buf, usage); free(buf); @@ -292,9 +318,11 @@ int gl_vertex_attrib_pointer(lua_State *L) lua_Integer index, size, stride, offset; bool normalized; hs_parse_args(L, hs_int(index), hs_int(size), hs_bool(normalized), hs_int(stride), hs_int(offset)); - glVertexAttribPointer(index, size, GL_FLOAT, + printf("normalized: %d\n", normalized); + /*glVertexAttribPointer(index, size, GL_FLOAT, normalized, stride*sizeof(float), - (void*) (offset*sizeof(float))); + (void*) (offset*sizeof(float)));*/ + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0); return 0; } @@ -333,3 +361,12 @@ int gl_draw_arrays(lua_State *L) glDrawArrays(mode, first, count); return 0; } + + +int gl_set_viewport(lua_State *L) +{ + lua_Integer x, y, w, h; + hs_parse_args(L, hs_int(x), hs_int(y), hs_int(w), hs_int(h)); + glViewport(x, y, w, h); + return 0; +} diff --git a/src/gl/gl.test.c b/src/gl/gl.test.c index aa24fd2..9782caf 100644 --- a/src/gl/gl.test.c +++ b/src/gl/gl.test.c @@ -67,10 +67,10 @@ void mock_glBufferData_(int target, size_t size, const void *data, int usage) }; lily_mock_store_call(mock_glBufferData, args); - size_t count = size/sizeof(lua_Number); - lua_Number *numbers = data; + size_t count = size/sizeof(float); + float *numbers = data; for (int i=0; i #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; +} 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); 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_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; @@ -35,6 +78,12 @@ int window_create(lua_State *L) 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; } @@ -60,6 +109,15 @@ int window_make_context_current(lua_State *L) } +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; @@ -85,3 +143,17 @@ int window_swap_buffers(lua_State *L) 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; +} diff --git a/src/gl/window.test.c b/src/gl/window.test.c new file mode 100644 index 0000000..505c876 --- /dev/null +++ b/src/gl/window.test.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include "test/honey-test.h" + +#include "window.c" + + +void create_window_data_works() +{ + lua_State *L = luaL_newstate(); + struct window_data *wdata = create_window_data(L); + + lily_assert_ptr_equal(L, wdata->L); + lily_assert_int_equal(wdata->framebuffer_size_callback, LUA_NOREF); + lua_close(L); + free(wdata); +} + + +void suite_window() +{ + lily_run_test(create_window_data_works); +} -- cgit v1.2.1 From bd5ae222cc1d2a24b55bd8aa8c72dd63f73cb35f Mon Sep 17 00:00:00 2001 From: sanine Date: Sun, 21 Aug 2022 18:49:49 -0500 Subject: use full gl_vertex_attrib_pointer --- src/gl/gl.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/gl') diff --git a/src/gl/gl.c b/src/gl/gl.c index 581cf39..f9419e2 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -196,13 +196,9 @@ int gl_buffer_data(lua_State *L) hs_throw_error(L, "all table items must be numbers (failed at index %d)", i); } buf[i] = lua_tonumber(L, -1); - printf(" [%d] %f\n", i, buf[i]); lua_pop(L, 1); } - printf("target: %d\n", target); - printf("GL_ARRAY_BUFFER: %d\n", GL_ARRAY_BUFFER); - /* call */ glBufferData(target, len*sizeof(float), buf, usage); free(buf); @@ -318,11 +314,9 @@ int gl_vertex_attrib_pointer(lua_State *L) lua_Integer index, size, stride, offset; bool normalized; hs_parse_args(L, hs_int(index), hs_int(size), hs_bool(normalized), hs_int(stride), hs_int(offset)); - printf("normalized: %d\n", normalized); - /*glVertexAttribPointer(index, size, GL_FLOAT, + glVertexAttribPointer(index, size, GL_FLOAT, normalized, stride*sizeof(float), - (void*) (offset*sizeof(float)));*/ - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0); + (void*) (offset*sizeof(float))); return 0; } -- cgit v1.2.1 From 68d4b40cd00dd0ec2f0ed09033f8e05a98e5ca2d Mon Sep 17 00:00:00 2001 From: sanine Date: Sun, 21 Aug 2022 21:58:39 -0500 Subject: fix segfault with wdata --- src/gl/window.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gl') diff --git a/src/gl/window.c b/src/gl/window.c index 5ed9427..075bd6c 100644 --- a/src/gl/window.c +++ b/src/gl/window.c @@ -16,6 +16,7 @@ struct window_data * create_window_data(lua_State *L) return NULL; wdata->L = L; wdata->framebuffer_size_callback = LUA_NOREF; + return wdata; } int window_create(lua_State *L); -- cgit v1.2.1 From 33f3eb1c5a489a1b0c7d508e6a42f0dbb20e3a1b Mon Sep 17 00:00:00 2001 From: sanine Date: Mon, 22 Aug 2022 09:08:59 -0500 Subject: add types to gl_buffer_data --- src/gl/gl.c | 48 +++++++++++++++++++++++++++++---------- src/gl/gl.test.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 98 insertions(+), 19 deletions(-) (limited to 'src/gl') diff --git a/src/gl/gl.c b/src/gl/gl.c index f9419e2..953cefb 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -181,26 +181,50 @@ int gl_bind_buffer(lua_State *L) int gl_buffer_data(lua_State *L) { - lua_Integer target, usage; + lua_Integer target, type, usage; int table; - hs_parse_args(L, hs_int(target), hs_tbl(table), hs_int(usage)); + hs_parse_args(L, hs_int(target), hs_int(type), hs_tbl(table), hs_int(usage)); + + if (type != GL_INT && type != GL_FLOAT) { + hs_throw_error(L, "invalid type"); + } /* build raw buffer */ size_t len = lua_objlen(L, table); - float *buf = malloc(len * sizeof(float)); - if (buf == NULL) - hs_throw_error(L, "failed to allocate intermediary buffer"); - for (int i=0; in_calls, 1); + int target; size_t size; int usage; + struct lily_mock_arg_t args[] = { + { sizeof(int), &target }, + { sizeof(size_t), &size }, + { sizeof(int), &usage } + }; + lily_mock_get_call(mock_glBufferData, args, 0); + lily_assert_int_equal(target, GL_ARRAY_BUFFER); + lily_assert_int_equal(size, 3*sizeof(float)); + lily_assert_int_equal(usage, GL_STATIC_DRAW); + + int n; + lily_get_value(mock_glBufferData, int, &n); + lily_assert_int_equal(n, 22); + lily_get_value(mock_glBufferData, int, &n); + lily_assert_int_equal(n, 33); + lily_get_value(mock_glBufferData, int, &n); + lily_assert_int_equal(n, 44); +} + void suite_gl() { lily_run_test(gl_init_succeeds); lily_run_test(gl_init_fails); lily_run_test(gl_terminate_works); - lily_run_test(gl_buffer_data_works); + lily_run_test(gl_buffer_float_works); + lily_run_test(gl_buffer_int_works); lily_mock_destroy(mock_glfwInit); lily_mock_destroy(mock_hs_throw_error); -- cgit v1.2.1 From f84ee69cdf694a1f64f2536efed4b7d0dd75553a Mon Sep 17 00:00:00 2001 From: sanine Date: Mon, 22 Aug 2022 09:12:09 -0500 Subject: make hello triangle work --- src/gl/gl.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gl') diff --git a/src/gl/gl.c b/src/gl/gl.c index 953cefb..cef93fa 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -47,6 +47,11 @@ int gl_clear(lua_State *L); void setup_gl(lua_State *L, int honey_index) { + int data_types = hs_create_table(L, + hs_str_int("integer", GL_INT), + hs_str_int("float", GL_FLOAT), + ); + int error_types = hs_create_table(L, hs_str_int("noError", GL_NO_ERROR), hs_str_int("invalidEnum", GL_INVALID_ENUM), @@ -89,6 +94,7 @@ void setup_gl(lua_State *L, int honey_index) hs_str_cfunc("terminate", gl_terminate), hs_str_cfunc("getError", gl_get_error), + hs_str_tbl("dataType", data_types), hs_str_tbl("errorType", error_types), /* buffer */ -- cgit v1.2.1 From 65ad3a58adcfe21690f379ab894a104b3852e3e9 Mon Sep 17 00:00:00 2001 From: sanine Date: Mon, 22 Aug 2022 10:31:56 -0500 Subject: refactor: move shader functions into separate file --- src/gl/gl.c | 120 +++--------------------------------------------------- src/gl/gl.h | 1 + src/gl/shader.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 115 deletions(-) create mode 100644 src/gl/shader.c (limited to 'src/gl') diff --git a/src/gl/gl.c b/src/gl/gl.c index cef93fa..d0fb33c 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -4,6 +4,7 @@ #include #include #include +#include "gl.h" /* needs to be here because glad uses macros to define glBufferData */ #ifdef HONEY_TEST_H @@ -27,17 +28,6 @@ int gl_vertex_array_bind(lua_State *L); int gl_vertex_attrib_pointer(lua_State *L); int gl_vertex_array_enable_attrib(lua_State *L); -/* shaders */ -int gl_create_shader(lua_State *L); -int gl_shader_set_source(lua_State *L); -int gl_shader_compile(lua_State *L); -int gl_shader_delete(lua_State *L); - -int gl_program_create(lua_State *L); -int gl_program_attach_shader(lua_State *L); -int gl_program_link(lua_State *L); -int gl_program_use(lua_State *L); - /* drawing */ int gl_set_viewport(lua_State *L); int gl_draw_arrays(lua_State *L); @@ -63,6 +53,7 @@ void setup_gl(lua_State *L, int honey_index) int buffer_binding_targets = hs_create_table(L, hs_str_int("arrayBuffer", GL_ARRAY_BUFFER), + hs_str_int("elementArrayBuffer", GL_ELEMENT_ARRAY_BUFFER), ); int buffer_usage_patterns = hs_create_table(L, @@ -71,11 +62,6 @@ void setup_gl(lua_State *L, int honey_index) hs_str_int("dynamicDraw", GL_DYNAMIC_DRAW), ); - int shader_types = hs_create_table(L, - hs_str_int("vertexShader", GL_VERTEX_SHADER), - hs_str_int("fragmentShader", GL_FRAGMENT_SHADER), - ); - int primitive_types = hs_create_table(L, hs_str_int("points", GL_POINTS), hs_str_int("lines", GL_LINES), @@ -88,7 +74,7 @@ void setup_gl(lua_State *L, int honey_index) hs_str_int("stencilBuffer", GL_STENCIL_BUFFER_BIT), ); - hs_create_table(L, + int gl_index = hs_create_table(L, hs_str_cfunc("init", gl_init), hs_str_cfunc("initGlad", glad_init), hs_str_cfunc("terminate", gl_terminate), @@ -110,19 +96,6 @@ void setup_gl(lua_State *L, int honey_index) hs_str_tbl("bufferTarget", buffer_binding_targets), hs_str_tbl("bufferUsage", buffer_usage_patterns), - /* shader */ - hs_str_cfunc("createShader", gl_create_shader), - hs_str_cfunc("setShaderSource", gl_shader_set_source), - hs_str_cfunc("compileShader", gl_shader_compile), - hs_str_cfunc("deleteShader", gl_shader_delete), - - hs_str_cfunc("createProgram", gl_program_create), - hs_str_cfunc("programAttachShader", gl_program_attach_shader), - hs_str_cfunc("linkProgram", gl_program_link), - hs_str_cfunc("useProgram", gl_program_use), - - hs_str_tbl("shaderType", shader_types), - /* drawing */ hs_str_cfunc("drawArrays", gl_draw_arrays), hs_str_cfunc("setClearColor", gl_set_clear_color), @@ -132,6 +105,8 @@ void setup_gl(lua_State *L, int honey_index) hs_str_tbl("primitiveType", primitive_types), hs_str_tbl("bufferMask", buffer_masks), ); + + setup_shader(L, gl_index); lua_setfield(L, honey_index, "gl"); } @@ -236,91 +211,6 @@ int gl_buffer_data(lua_State *L) } -int gl_create_shader(lua_State *L) -{ - lua_Integer type; - hs_parse_args(L, hs_int(type)); - lua_Integer shader = glCreateShader(type); - lua_pushinteger(L, shader); - return 1; -} - - -int gl_shader_set_source(lua_State *L) -{ - lua_Integer shader; - char *code; - hs_parse_args(L, hs_int(shader), hs_str(code)); - glShaderSource(shader, 1, &code, NULL); - return 0; -} - - -int gl_shader_compile(lua_State *L) -{ - lua_Integer shader; - hs_parse_args(L, hs_int(shader)); - glCompileShader(shader); - int success; char log[1024]; - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(shader, 1024, NULL, log); - hs_throw_error(L, "shader compilation failed: %s", log); - } - return 0; -} - - -int gl_shader_delete(lua_State *L) -{ - lua_Integer shader; - hs_parse_args(L, hs_int(shader)); - glDeleteShader(shader); - return 0; -} - - -int gl_program_create(lua_State *L) -{ - lua_Integer program = glCreateProgram(); - lua_pushinteger(L, program); - return 1; -} - - -int gl_program_attach_shader(lua_State *L) -{ - lua_Integer program, shader; - hs_parse_args(L, hs_int(program), hs_int(shader)), - glAttachShader(program, shader); - return 0; -} - - -int gl_program_link(lua_State *L) -{ - lua_Integer program; - hs_parse_args(L, hs_int(program)); - glLinkProgram(program); - int success; char log[1024]; - glGetProgramiv(program, GL_LINK_STATUS, &success); - if (!success) { - glGetProgramInfoLog(program, 1024, NULL, log); - hs_throw_error(L, "shader linking failed: %s", log); - } - return 0; -} - - -int gl_program_use(lua_State *L) -{ - lua_Integer program; - hs_parse_args(L, hs_int(program)); - glUseProgram(program); - return 0; -} - - int gl_vertex_array_create(lua_State *L) { int array; diff --git a/src/gl/gl.h b/src/gl/gl.h index 2e27851..b209957 100644 --- a/src/gl/gl.h +++ b/src/gl/gl.h @@ -4,6 +4,7 @@ #include void setup_gl(lua_State *L, int honey_index); +void setup_shader(lua_State *L, int gl_index); void setup_window(lua_State *L, int honey_index); #endif diff --git a/src/gl/shader.c b/src/gl/shader.c new file mode 100644 index 0000000..96946fe --- /dev/null +++ b/src/gl/shader.c @@ -0,0 +1,124 @@ +#include "gl/glad/glad.h" +#include +#include +#include + +int gl_create_shader(lua_State *L); +int gl_shader_set_source(lua_State *L); +int gl_shader_compile(lua_State *L); +int gl_shader_delete(lua_State *L); + +int gl_program_create(lua_State *L); +int gl_program_attach_shader(lua_State *L); +int gl_program_link(lua_State *L); +int gl_program_use(lua_State *L); + + +void setup_shader(lua_State *L, int gl_index) +{ + int shader_types = hs_create_table(L, + hs_str_int("vertexShader", GL_VERTEX_SHADER), + hs_str_int("fragmentShader", GL_FRAGMENT_SHADER), + ); + + hs_create_table(L, + hs_str_cfunc("create", gl_create_shader), + hs_str_cfunc("setSource", gl_shader_set_source), + hs_str_cfunc("compile", gl_shader_compile), + hs_str_cfunc("delete", gl_shader_delete), + + hs_str_cfunc("createProgram", gl_program_create), + hs_str_cfunc("attachShader", gl_program_attach_shader), + hs_str_cfunc("link", gl_program_link), + hs_str_cfunc("use", gl_program_use), + + hs_str_tbl("type", shader_types), + ); + + lua_setfield(L, gl_index, "shader"); +} + + +int gl_create_shader(lua_State *L) +{ + lua_Integer type; + hs_parse_args(L, hs_int(type)); + lua_Integer shader = glCreateShader(type); + lua_pushinteger(L, shader); + return 1; +} + + +int gl_shader_set_source(lua_State *L) +{ + lua_Integer shader; + char *code; + hs_parse_args(L, hs_int(shader), hs_str(code)); + glShaderSource(shader, 1, &code, NULL); + return 0; +} + + +int gl_shader_compile(lua_State *L) +{ + lua_Integer shader; + hs_parse_args(L, hs_int(shader)); + glCompileShader(shader); + int success; char log[1024]; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(shader, 1024, NULL, log); + hs_throw_error(L, "shader compilation failed: %s", log); + } + return 0; +} + + +int gl_shader_delete(lua_State *L) +{ + lua_Integer shader; + hs_parse_args(L, hs_int(shader)); + glDeleteShader(shader); + return 0; +} + + +int gl_program_create(lua_State *L) +{ + lua_Integer program = glCreateProgram(); + lua_pushinteger(L, program); + return 1; +} + + +int gl_program_attach_shader(lua_State *L) +{ + lua_Integer program, shader; + hs_parse_args(L, hs_int(program), hs_int(shader)), + glAttachShader(program, shader); + return 0; +} + + +int gl_program_link(lua_State *L) +{ + lua_Integer program; + hs_parse_args(L, hs_int(program)); + glLinkProgram(program); + int success; char log[1024]; + glGetProgramiv(program, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(program, 1024, NULL, log); + hs_throw_error(L, "shader linking failed: %s", log); + } + return 0; +} + + +int gl_program_use(lua_State *L) +{ + lua_Integer program; + hs_parse_args(L, hs_int(program)); + glUseProgram(program); + return 0; +} -- cgit v1.2.1 From dccc9bef56d51c5cad13c2568c5a3b97f637fd6e Mon Sep 17 00:00:00 2001 From: sanine Date: Mon, 22 Aug 2022 10:45:52 -0500 Subject: refactor: move drawing code into separate file --- src/gl/drawing.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/gl/gl.c | 65 +-------------------------------------------------- src/gl/gl.h | 2 ++ src/gl/gl.test.c | 4 ++++ 4 files changed, 78 insertions(+), 64 deletions(-) create mode 100644 src/gl/drawing.c (limited to 'src/gl') diff --git a/src/gl/drawing.c b/src/gl/drawing.c new file mode 100644 index 0000000..a64f56d --- /dev/null +++ b/src/gl/drawing.c @@ -0,0 +1,71 @@ +#include "gl/glad/glad.h" +#include +#include +#include + +int gl_set_viewport(lua_State *L); +int gl_draw_arrays(lua_State *L); +int gl_set_clear_color(lua_State *L); +int gl_clear(lua_State *L); + +void setup_drawing(lua_State *L, int gl_index) +{ + int primitive_types = hs_create_table(L, + hs_str_int("points", GL_POINTS), + hs_str_int("lines", GL_LINES), + hs_str_int("triangles", GL_TRIANGLES), + ); + + int buffer_masks = hs_create_table(L, + hs_str_int("colorBuffer", GL_COLOR_BUFFER_BIT), + hs_str_int("depthBuffer", GL_DEPTH_BUFFER_BIT), + hs_str_int("stencilBuffer", GL_STENCIL_BUFFER_BIT), + ); + + hs_create_table(L, + hs_str_cfunc("drawArrays", gl_draw_arrays), + hs_str_cfunc("setClearColor", gl_set_clear_color), + hs_str_cfunc("clear", gl_clear), + hs_str_cfunc("setViewport", gl_set_viewport), + + hs_str_tbl("primitiveType", primitive_types), + hs_str_tbl("bufferMask", buffer_masks), + ); + + lua_setfield(L, gl_index, "draw"); +} + +int gl_set_clear_color(lua_State *L) +{ + lua_Number r, g, b, a; + hs_parse_args(L, hs_num(r), hs_num(g), hs_num(b), hs_num(a)); + glClearColor(r, g, b, a); + return 0; +} + + +int gl_clear(lua_State *L) +{ + lua_Integer mask; + hs_parse_args(L, hs_int(mask)); + glClear(mask); + return 0; +} + + +int gl_draw_arrays(lua_State *L) +{ + lua_Integer mode, first, count; + hs_parse_args(L, hs_int(mode), hs_int(first), hs_int(count)); + glDrawArrays(mode, first, count); + return 0; +} + + +int gl_set_viewport(lua_State *L) +{ + lua_Integer x, y, w, h; + hs_parse_args(L, hs_int(x), hs_int(y), hs_int(w), hs_int(h)); + glViewport(x, y, w, h); + return 0; +} diff --git a/src/gl/gl.c b/src/gl/gl.c index d0fb33c..876df9d 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -28,13 +28,6 @@ int gl_vertex_array_bind(lua_State *L); int gl_vertex_attrib_pointer(lua_State *L); int gl_vertex_array_enable_attrib(lua_State *L); -/* drawing */ -int gl_set_viewport(lua_State *L); -int gl_draw_arrays(lua_State *L); -int gl_set_clear_color(lua_State *L); -int gl_clear(lua_State *L); - - void setup_gl(lua_State *L, int honey_index) { int data_types = hs_create_table(L, @@ -62,18 +55,6 @@ void setup_gl(lua_State *L, int honey_index) hs_str_int("dynamicDraw", GL_DYNAMIC_DRAW), ); - int primitive_types = hs_create_table(L, - hs_str_int("points", GL_POINTS), - hs_str_int("lines", GL_LINES), - hs_str_int("triangles", GL_TRIANGLES), - ); - - int buffer_masks = hs_create_table(L, - hs_str_int("colorBuffer", GL_COLOR_BUFFER_BIT), - hs_str_int("depthBuffer", GL_DEPTH_BUFFER_BIT), - hs_str_int("stencilBuffer", GL_STENCIL_BUFFER_BIT), - ); - int gl_index = hs_create_table(L, hs_str_cfunc("init", gl_init), hs_str_cfunc("initGlad", glad_init), @@ -95,18 +76,10 @@ void setup_gl(lua_State *L, int honey_index) hs_str_tbl("bufferTarget", buffer_binding_targets), hs_str_tbl("bufferUsage", buffer_usage_patterns), - - /* drawing */ - hs_str_cfunc("drawArrays", gl_draw_arrays), - hs_str_cfunc("setClearColor", gl_set_clear_color), - hs_str_cfunc("clear", gl_clear), - hs_str_cfunc("setViewport", gl_set_viewport), - - hs_str_tbl("primitiveType", primitive_types), - hs_str_tbl("bufferMask", buffer_masks), ); setup_shader(L, gl_index); + setup_drawing(L, gl_index); lua_setfield(L, honey_index, "gl"); } @@ -248,39 +221,3 @@ int gl_vertex_array_enable_attrib(lua_State *L) glEnableVertexAttribArray(index); return 0; } - - -int gl_set_clear_color(lua_State *L) -{ - lua_Number r, g, b, a; - hs_parse_args(L, hs_num(r), hs_num(g), hs_num(b), hs_num(a)); - glClearColor(r, g, b, a); - return 0; -} - - -int gl_clear(lua_State *L) -{ - lua_Integer mask; - hs_parse_args(L, hs_int(mask)); - glClear(mask); - return 0; -} - - -int gl_draw_arrays(lua_State *L) -{ - lua_Integer mode, first, count; - hs_parse_args(L, hs_int(mode), hs_int(first), hs_int(count)); - glDrawArrays(mode, first, count); - return 0; -} - - -int gl_set_viewport(lua_State *L) -{ - lua_Integer x, y, w, h; - hs_parse_args(L, hs_int(x), hs_int(y), hs_int(w), hs_int(h)); - glViewport(x, y, w, h); - return 0; -} diff --git a/src/gl/gl.h b/src/gl/gl.h index b209957..f384c54 100644 --- a/src/gl/gl.h +++ b/src/gl/gl.h @@ -5,6 +5,8 @@ void setup_gl(lua_State *L, int honey_index); void setup_shader(lua_State *L, int gl_index); +void setup_drawing(lua_State *L, int gl_index); + void setup_window(lua_State *L, int honey_index); #endif diff --git a/src/gl/gl.test.c b/src/gl/gl.test.c index bab8529..363036a 100644 --- a/src/gl/gl.test.c +++ b/src/gl/gl.test.c @@ -10,11 +10,15 @@ int mock_hs_throw_error_(lua_State *L, const char *str, ...); void mock_glfwTerminate_(); void mock_glBufferData_(int, size_t, const void *, int); +#define DUMMY_FUNCTION(...) + #define glfwInit mock_glfwInit_ #define hs_throw_error mock_hs_throw_error_ #define glfwTerminate mock_glfwTerminate_ #undef glBufferData #define glBufferData mock_glBufferData_ +#define setup_shader DUMMY_FUNCTION +#define setup_drawing DUMMY_FUNCTION #include "gl/gl.c" #undef glBufferData #undef glfwTerminate -- cgit v1.2.1 From a2c162f12337142c054c2e1f01ad508ee56963d2 Mon Sep 17 00:00:00 2001 From: sanine Date: Mon, 22 Aug 2022 11:00:42 -0500 Subject: refactor: move data functions into separate file --- src/gl/data.c | 155 ++++++++++++++++++++++++++++++++++++++ src/gl/data.test.c | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/gl/gl.c | 143 +---------------------------------- src/gl/gl.h | 1 + src/gl/gl.test.c | 1 + 5 files changed, 374 insertions(+), 142 deletions(-) create mode 100644 src/gl/data.c create mode 100644 src/gl/data.test.c (limited to 'src/gl') diff --git a/src/gl/data.c b/src/gl/data.c new file mode 100644 index 0000000..f598784 --- /dev/null +++ b/src/gl/data.c @@ -0,0 +1,155 @@ +#include +#include +#include "gl/glad/glad.h" +#include +#include +#include +#include "gl.h" + +int gl_create_buffer(lua_State *L); +int gl_bind_buffer(lua_State *L); +int gl_buffer_data(lua_State *L); + +int gl_vertex_array_create(lua_State *L); +int gl_vertex_array_bind(lua_State *L); +int gl_vertex_attrib_pointer(lua_State *L); +int gl_vertex_array_enable_attrib(lua_State *L); + + +void setup_data(lua_State *L, int gl_index) +{ + int buffer_binding_targets = hs_create_table(L, + hs_str_int("arrayBuffer", GL_ARRAY_BUFFER), + hs_str_int("elementArrayBuffer", GL_ELEMENT_ARRAY_BUFFER), + ); + + int buffer_usage_patterns = hs_create_table(L, + hs_str_int("streamDraw", GL_STREAM_DRAW), + hs_str_int("staticDraw", GL_STATIC_DRAW), + hs_str_int("dynamicDraw", GL_DYNAMIC_DRAW), + ); + + hs_create_table(L, + hs_str_cfunc("createBuffer", gl_create_buffer), + hs_str_cfunc("bindBuffer", gl_bind_buffer), + hs_str_cfunc("bufferData", gl_buffer_data), + + hs_str_cfunc("createVertexArray", gl_vertex_array_create), + hs_str_cfunc("bindVertexArray", gl_vertex_array_bind), + hs_str_cfunc("vertexAttribPointer", gl_vertex_attrib_pointer), + hs_str_cfunc("vertexArrayEnableAttrib", gl_vertex_array_enable_attrib), + + hs_str_tbl("bufferTarget", buffer_binding_targets), + hs_str_tbl("bufferUsage", buffer_usage_patterns), + ); + + lua_setfield(L, gl_index, "data"); +} + + +int gl_create_buffer(lua_State *L) +{ + int buf; + glGenBuffers(1, &buf); + lua_pushinteger(L, buf); + return 1; +} + + +int gl_bind_buffer(lua_State *L) +{ + lua_Integer target, buf; + hs_parse_args(L, hs_int(target), hs_int(buf)); + glBindBuffer(target, buf); + return 0; +} + + +int gl_buffer_data(lua_State *L) +{ + lua_Integer target, type, usage; + int table; + hs_parse_args(L, hs_int(target), hs_int(type), hs_tbl(table), hs_int(usage)); + + if (type != GL_INT && type != GL_FLOAT) { + hs_throw_error(L, "invalid type"); + } + + /* build raw buffer */ + size_t len = lua_objlen(L, table); + void *buf; + if (type == GL_FLOAT) { + float *fbuf = malloc(len * sizeof(float)); + if (fbuf == NULL) + hs_throw_error(L, "failed to allocate intermediary fbuffer"); + for (int i=0; i +#include +#include +#include +#include "test/honey-test.h" + + +int mock_glfwInit_(void); +int mock_hs_throw_error_(lua_State *L, const char *str, ...); +void mock_glfwTerminate_(); +void mock_glBufferData_(int, size_t, const void *, int); + +#define DUMMY_FUNCTION(...) + +#define glfwInit mock_glfwInit_ +#define hs_throw_error mock_hs_throw_error_ +#define glfwTerminate mock_glfwTerminate_ +#undef glBufferData +#define glBufferData mock_glBufferData_ +#define setup_shader DUMMY_FUNCTION +#define setup_drawing DUMMY_FUNCTION +#include "gl/gl.c" +#undef glBufferData +#undef glfwTerminate +#undef hs_throw_error +#undef glfwInit + + +lily_mock_t *mock_hs_throw_error = NULL; +static int mock_hs_throw_error_(lua_State *L, const char *str, ...) +{ + struct lily_mock_arg_t args[] = { + { sizeof(const char *), &str } + }; + lily_mock_store_call(mock_hs_throw_error, args); + + lua_pushstring(L, "some error"); + lua_error(L); + + return 0; +} + +lily_mock_t *mock_glBufferData = NULL; +static void mock_glBufferData_(int target, size_t size, const void *data, int usage) +{ + struct lily_mock_arg_t args[] = { + { sizeof(int), &target }, + { sizeof(size_t), &size }, + { sizeof(int), &usage } + }; + lily_mock_store_call(mock_glBufferData, args); + + int use_ints; lily_get_value(mock_glBufferData, int, &use_ints); + + if (use_ints) { + size_t count = size/sizeof(int); + int *numbers = data; + for (int i=0; in_calls, 1); + lily_assert_int_equal(mock_hs_throw_error->n_calls, 0); +} + + +void gl_init_fails() +{ + lily_mock_use(&mock_glfwInit); + lily_mock_use(&mock_hs_throw_error); + + lua_State *L = luaL_newstate(); + lily_store_value(mock_glfwInit, int, 0); + lua_pushcfunction(L, gl_init); + int err = lua_pcall(L, 0, 0, 0); + lua_close(L); + + lily_assert_int_equal(err, LUA_ERRRUN); + lily_assert_int_equal(mock_hs_throw_error->n_calls, 1); +} + + +void gl_terminate_works() +{ + lily_mock_use(&mock_glfwTerminate); + + lua_State *L = luaL_newstate(); + lua_pushcfunction(L, gl_terminate); + int err = lua_pcall(L, 0, 0, 0); + lua_close(L); + + lily_assert_int_equal(err, 0); + lily_assert_int_equal(mock_glfwTerminate->n_calls, 1); +} + + +void gl_buffer_float_works() +{ + lily_mock_use(&mock_hs_throw_error); + lily_mock_use(&mock_glBufferData); + lily_store_value(mock_glBufferData, int, 0); // use floats + + lua_State *L = luaL_newstate(); + lua_pushcfunction(L, gl_buffer_data); + lua_pushinteger(L, GL_ARRAY_BUFFER); + lua_pushinteger(L, GL_FLOAT); + hs_create_table(L, + hs_int_num(1, 22), + hs_int_num(2, 33), + hs_int_num(3, 44), + ); + lua_pushinteger(L, GL_STATIC_DRAW); + int err = hs_call(L, 4, 0); + lua_close(L); + + lily_assert_int_equal(err, 0); + lily_assert_int_equal(mock_glBufferData->n_calls, 1); + int target; size_t size; int usage; + struct lily_mock_arg_t args[] = { + { sizeof(int), &target }, + { sizeof(size_t), &size }, + { sizeof(int), &usage } + }; + lily_mock_get_call(mock_glBufferData, args, 0); + lily_assert_int_equal(target, GL_ARRAY_BUFFER); + lily_assert_int_equal(size, 3*sizeof(float)); + lily_assert_int_equal(usage, GL_STATIC_DRAW); + + float n; + lily_get_value(mock_glBufferData, float, &n); + lily_assert_float_equal(n, 22, 0.1); + lily_get_value(mock_glBufferData, float, &n); + lily_assert_float_equal(n, 33, 0.1); + lily_get_value(mock_glBufferData, float, &n); + lily_assert_float_equal(n, 44, 0.1); +} + + +void gl_buffer_int_works() +{ + lily_mock_use(&mock_hs_throw_error); + lily_mock_use(&mock_glBufferData); + lily_store_value(mock_glBufferData, int, 1); // use ints + + lua_State *L = luaL_newstate(); + lua_pushcfunction(L, gl_buffer_data); + lua_pushinteger(L, GL_ARRAY_BUFFER); + lua_pushinteger(L, GL_INT); + hs_create_table(L, + hs_int_num(1, 22), + hs_int_num(2, 33), + hs_int_num(3, 44), + ); + lua_pushinteger(L, GL_STATIC_DRAW); + int err = hs_call(L, 4, 0); + lua_close(L); + + lily_assert_int_equal(err, 0); + lily_assert_int_equal(mock_glBufferData->n_calls, 1); + int target; size_t size; int usage; + struct lily_mock_arg_t args[] = { + { sizeof(int), &target }, + { sizeof(size_t), &size }, + { sizeof(int), &usage } + }; + lily_mock_get_call(mock_glBufferData, args, 0); + lily_assert_int_equal(target, GL_ARRAY_BUFFER); + lily_assert_int_equal(size, 3*sizeof(float)); + lily_assert_int_equal(usage, GL_STATIC_DRAW); + + int n; + lily_get_value(mock_glBufferData, int, &n); + lily_assert_int_equal(n, 22); + lily_get_value(mock_glBufferData, int, &n); + lily_assert_int_equal(n, 33); + lily_get_value(mock_glBufferData, int, &n); + lily_assert_int_equal(n, 44); +} + +void suite_gl() +{ + lily_run_test(gl_init_succeeds); + lily_run_test(gl_init_fails); + lily_run_test(gl_terminate_works); + lily_run_test(gl_buffer_float_works); + lily_run_test(gl_buffer_int_works); + + lily_mock_destroy(mock_glfwInit); + lily_mock_destroy(mock_hs_throw_error); + lily_mock_destroy(mock_glfwTerminate); + lily_mock_destroy(mock_glBufferData); +} diff --git a/src/gl/gl.c b/src/gl/gl.c index 876df9d..8a1cb17 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -18,16 +18,6 @@ int glad_init(lua_State *L); int gl_terminate(lua_State *L); int gl_get_error(lua_State *L); -/* buffers */ -int gl_create_buffer(lua_State *L); -int gl_bind_buffer(lua_State *L); -int gl_buffer_data(lua_State *L); - -int gl_vertex_array_create(lua_State *L); -int gl_vertex_array_bind(lua_State *L); -int gl_vertex_attrib_pointer(lua_State *L); -int gl_vertex_array_enable_attrib(lua_State *L); - void setup_gl(lua_State *L, int honey_index) { int data_types = hs_create_table(L, @@ -44,17 +34,6 @@ void setup_gl(lua_State *L, int honey_index) hs_str_int("outOfMemory", GL_OUT_OF_MEMORY), ); - int buffer_binding_targets = hs_create_table(L, - hs_str_int("arrayBuffer", GL_ARRAY_BUFFER), - hs_str_int("elementArrayBuffer", GL_ELEMENT_ARRAY_BUFFER), - ); - - int buffer_usage_patterns = hs_create_table(L, - hs_str_int("streamDraw", GL_STREAM_DRAW), - hs_str_int("staticDraw", GL_STATIC_DRAW), - hs_str_int("dynamicDraw", GL_DYNAMIC_DRAW), - ); - int gl_index = hs_create_table(L, hs_str_cfunc("init", gl_init), hs_str_cfunc("initGlad", glad_init), @@ -63,23 +42,11 @@ void setup_gl(lua_State *L, int honey_index) hs_str_tbl("dataType", data_types), hs_str_tbl("errorType", error_types), - - /* buffer */ - hs_str_cfunc("createBuffer", gl_create_buffer), - hs_str_cfunc("bindBuffer", gl_bind_buffer), - hs_str_cfunc("bufferData", gl_buffer_data), - - hs_str_cfunc("createVertexArray", gl_vertex_array_create), - hs_str_cfunc("bindVertexArray", gl_vertex_array_bind), - hs_str_cfunc("vertexAttribPointer", gl_vertex_attrib_pointer), - hs_str_cfunc("vertexArrayEnableAttrib", gl_vertex_array_enable_attrib), - - hs_str_tbl("bufferTarget", buffer_binding_targets), - hs_str_tbl("bufferUsage", buffer_usage_patterns), ); setup_shader(L, gl_index); setup_drawing(L, gl_index); + setup_data(L, gl_index); lua_setfield(L, honey_index, "gl"); } @@ -113,111 +80,3 @@ int gl_get_error(lua_State *L) lua_pushinteger(L, glGetError()); return 1; } - - -int gl_create_buffer(lua_State *L) -{ - int buf; - glGenBuffers(1, &buf); - lua_pushinteger(L, buf); - return 1; -} - - -int gl_bind_buffer(lua_State *L) -{ - lua_Integer target, buf; - hs_parse_args(L, hs_int(target), hs_int(buf)); - glBindBuffer(target, buf); - return 0; -} - - -int gl_buffer_data(lua_State *L) -{ - lua_Integer target, type, usage; - int table; - hs_parse_args(L, hs_int(target), hs_int(type), hs_tbl(table), hs_int(usage)); - - if (type != GL_INT && type != GL_FLOAT) { - hs_throw_error(L, "invalid type"); - } - - /* build raw buffer */ - size_t len = lua_objlen(L, table); - void *buf; - if (type == GL_FLOAT) { - float *fbuf = malloc(len * sizeof(float)); - if (fbuf == NULL) - hs_throw_error(L, "failed to allocate intermediary fbuffer"); - for (int i=0; i Date: Mon, 22 Aug 2022 11:38:26 -0500 Subject: add element buffers --- src/gl/data.c | 72 +++++++++++++++++++++++++++++--------------------------- src/gl/drawing.c | 11 +++++++++ src/gl/gl.c | 3 ++- 3 files changed, 50 insertions(+), 36 deletions(-) (limited to 'src/gl') diff --git a/src/gl/data.c b/src/gl/data.c index f598784..777689a 100644 --- a/src/gl/data.c +++ b/src/gl/data.c @@ -65,48 +65,50 @@ int gl_bind_buffer(lua_State *L) } +#define GET_BUFFER_TYPE(type, name, conversion) \ + void * get_buffer_ ## name (lua_State *L, size_t *sz, int tbl) { \ + size_t len = lua_objlen(L, tbl); \ + *sz = len * sizeof(type); \ + type *buf = malloc(*sz); \ + if (buf == NULL) \ + hs_throw_error(L, "failed to allocate intermediary buffer"); \ + for (int i=0; i Date: Mon, 22 Aug 2022 12:39:51 -0500 Subject: add uniforms --- src/gl/CMakeLists.txt | 12 ++++++++++++ src/gl/shader.c | 27 +++++++++++++++++++++++++++ src/gl/window.c | 10 ++++++++++ 3 files changed, 49 insertions(+) create mode 100644 src/gl/CMakeLists.txt (limited to 'src/gl') diff --git a/src/gl/CMakeLists.txt b/src/gl/CMakeLists.txt new file mode 100644 index 0000000..f995ef5 --- /dev/null +++ b/src/gl/CMakeLists.txt @@ -0,0 +1,12 @@ +project(honey_engine) + +set (GL ${CMAKE_CURRENT_LIST_DIR}) + +target_sources(honey PUBLIC + ${GL}/data.c + ${GL}/drawing.c + ${GL}/shader.c + ${GL}/window.c + ${GL}/gl.c + ${GL}/glad/glad.c +) diff --git a/src/gl/shader.c b/src/gl/shader.c index 96946fe..fb64bc0 100644 --- a/src/gl/shader.c +++ b/src/gl/shader.c @@ -13,6 +13,9 @@ int gl_program_attach_shader(lua_State *L); int gl_program_link(lua_State *L); int gl_program_use(lua_State *L); +int gl_uniform_get_location(lua_State *L); +int gl_uniform_4f(lua_State *L); + void setup_shader(lua_State *L, int gl_index) { @@ -32,6 +35,9 @@ void setup_shader(lua_State *L, int gl_index) hs_str_cfunc("link", gl_program_link), hs_str_cfunc("use", gl_program_use), + hs_str_cfunc("getUniformLocation", gl_uniform_get_location), + hs_str_cfunc("uniform4f", gl_uniform_4f), + hs_str_tbl("type", shader_types), ); @@ -122,3 +128,24 @@ int gl_program_use(lua_State *L) glUseProgram(program); return 0; } + + +int gl_uniform_get_location(lua_State *L) +{ + lua_Integer program; + char *name; + hs_parse_args(L, hs_int(program), hs_str(name)); + int location = glGetUniformLocation(program, (const GLchar*)name); + lua_pushinteger(L, location); + return 1; +} + + +int gl_uniform_4f(lua_State *L) +{ + lua_Integer location; + lua_Number v0, v1, v2, v3; + hs_parse_args(L, hs_int(location), hs_num(v0), hs_num(v1), hs_num(v2), hs_num(v3)); + glUniform4f(location, v0, v1, v2, v3); + return 0; +} diff --git a/src/gl/window.c b/src/gl/window.c index 075bd6c..1b8c4bb 100644 --- a/src/gl/window.c +++ b/src/gl/window.c @@ -27,6 +27,8 @@ 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) @@ -50,6 +52,7 @@ void setup_window(lua_State *L, int honey_index) 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), @@ -158,3 +161,10 @@ int window_set_framebuffer_size_callback(lua_State *L) wdata->framebuffer_size_callback = hs_rstore(L); return 0; } + + +int window_get_time(lua_State *L) +{ + lua_pushnumber(L, glfwGetTime()); + return 1; +} -- cgit v1.2.1 From 1f47b685f35455afcc7441389cdc60018f66d159 Mon Sep 17 00:00:00 2001 From: sanine Date: Mon, 22 Aug 2022 15:55:44 -0500 Subject: add textures --- src/gl/CMakeLists.txt | 1 + src/gl/gl.c | 2 ++ src/gl/gl.h | 1 + src/gl/shader.c | 11 ++++++ src/gl/texture.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+) create mode 100644 src/gl/texture.c (limited to 'src/gl') diff --git a/src/gl/CMakeLists.txt b/src/gl/CMakeLists.txt index f995ef5..d4bc770 100644 --- a/src/gl/CMakeLists.txt +++ b/src/gl/CMakeLists.txt @@ -7,6 +7,7 @@ target_sources(honey PUBLIC ${GL}/drawing.c ${GL}/shader.c ${GL}/window.c + ${GL}/texture.c ${GL}/gl.c ${GL}/glad/glad.c ) diff --git a/src/gl/gl.c b/src/gl/gl.c index 8f56d33..c4502dc 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -21,6 +21,7 @@ int gl_get_error(lua_State *L); void setup_gl(lua_State *L, int honey_index) { int data_types = hs_create_table(L, + hs_str_int("uchar", GL_UNSIGNED_BYTE), hs_str_int("uint", GL_UNSIGNED_INT), hs_str_int("int", GL_INT), hs_str_int("float", GL_FLOAT), @@ -48,6 +49,7 @@ void setup_gl(lua_State *L, int honey_index) setup_shader(L, gl_index); setup_drawing(L, gl_index); setup_data(L, gl_index); + setup_texture(L, gl_index); lua_setfield(L, honey_index, "gl"); } diff --git a/src/gl/gl.h b/src/gl/gl.h index 766fe63..8aa1ef7 100644 --- a/src/gl/gl.h +++ b/src/gl/gl.h @@ -7,6 +7,7 @@ void setup_gl(lua_State *L, int honey_index); void setup_shader(lua_State *L, int gl_index); void setup_drawing(lua_State *L, int gl_index); void setup_data(lua_State *L, int gl_index); +void setup_texture(lua_State *L, int gl_index); void setup_window(lua_State *L, int honey_index); diff --git a/src/gl/shader.c b/src/gl/shader.c index fb64bc0..c3b409c 100644 --- a/src/gl/shader.c +++ b/src/gl/shader.c @@ -14,6 +14,7 @@ int gl_program_link(lua_State *L); int gl_program_use(lua_State *L); int gl_uniform_get_location(lua_State *L); +int gl_uniform_1i(lua_State *L); int gl_uniform_4f(lua_State *L); @@ -36,6 +37,7 @@ void setup_shader(lua_State *L, int gl_index) hs_str_cfunc("use", gl_program_use), hs_str_cfunc("getUniformLocation", gl_uniform_get_location), + hs_str_cfunc("uniform1i", gl_uniform_1i), hs_str_cfunc("uniform4f", gl_uniform_4f), hs_str_tbl("type", shader_types), @@ -141,6 +143,15 @@ int gl_uniform_get_location(lua_State *L) } +int gl_uniform_1i(lua_State *L) +{ + lua_Integer location, v0; + hs_parse_args(L, hs_int(location), hs_int(v0)); + glUniform1i(location, v0); + return 0; +} + + int gl_uniform_4f(lua_State *L) { lua_Integer location; diff --git a/src/gl/texture.c b/src/gl/texture.c new file mode 100644 index 0000000..d0c3a0a --- /dev/null +++ b/src/gl/texture.c @@ -0,0 +1,93 @@ +#include "gl/glad/glad.h" +#include +#include +#include + + +int gl_texture_create(lua_State *L); +int gl_texture_bind(lua_State *L); +int gl_texture_image_2d(lua_State *L); +int gl_texture_generate_mipmaps(lua_State *L); +int gl_texture_set_active(lua_State *L); + + +void setup_texture(lua_State *L, int gl_index) +{ + int bind_targets = hs_create_table(L, + hs_str_int("texture2d", GL_TEXTURE_2D), + ); + + int formats = hs_create_table(L, + hs_str_int("rgb", GL_RGB), + hs_str_int("rgba", GL_RGBA), + ); + + hs_create_table(L, + hs_str_cfunc("create", gl_texture_create), + hs_str_cfunc("bind", gl_texture_bind), + hs_str_cfunc("bufferImage2d", gl_texture_image_2d), + hs_str_cfunc("generateMipmaps", gl_texture_generate_mipmaps), + hs_str_cfunc("setActiveUnit", gl_texture_set_active), + + hs_str_tbl("bindTarget", bind_targets), + hs_str_tbl("format", formats), + ); + + lua_setfield(L, gl_index, "texture"); +} + + +int gl_texture_create(lua_State *L) +{ + unsigned int texture; + glGenTextures(1, &texture); + lua_pushinteger(L, texture); + return 1; +} + + +int gl_texture_bind(lua_State *L) +{ + lua_Integer target, texture; + hs_parse_args(L, hs_int(target), hs_int(texture)); + glBindTexture(target, texture); + return 0; +} + + +int gl_texture_image_2d(lua_State *L) +{ + lua_Integer target, mipmap_level, + internal_format, + width, height, + format, type; + void *data; + hs_parse_args(L, + hs_int(target), hs_int(mipmap_level), + hs_int(internal_format), + hs_int(width), hs_int(height), + hs_int(format), hs_int(type), + hs_light(data) + ); + + glTexImage2D(target, mipmap_level, internal_format, width, height, 0, format, type, data); + return 0; +} + + +int gl_texture_generate_mipmaps(lua_State *L) +{ + lua_Integer target; + hs_parse_args(L, hs_int(target)); + glGenerateMipmap(target); + return 0; +} + + +int gl_texture_set_active(lua_State *L) +{ + lua_Integer unit; + hs_parse_args(L, hs_int(unit)); + glActiveTexture(GL_TEXTURE0 + unit); + return 0; +} -- cgit v1.2.1 From 1f75a21851b0a0bd4bc766c458e67721dd37c9fd Mon Sep 17 00:00:00 2001 From: sanine Date: Mon, 22 Aug 2022 21:37:12 -0500 Subject: add append_table() --- src/gl/CMakeLists.txt | 7 +++++++ src/gl/gl.test.c | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/gl') diff --git a/src/gl/CMakeLists.txt b/src/gl/CMakeLists.txt index d4bc770..c1c3db0 100644 --- a/src/gl/CMakeLists.txt +++ b/src/gl/CMakeLists.txt @@ -11,3 +11,10 @@ target_sources(honey PUBLIC ${GL}/gl.c ${GL}/glad/glad.c ) + + +target_sources(test PUBLIC + ${GL}/glad/glad.c + ${GL}/gl.test.c + ${GL}/window.test.c +) diff --git a/src/gl/gl.test.c b/src/gl/gl.test.c index 7a687b4..488126f 100644 --- a/src/gl/gl.test.c +++ b/src/gl/gl.test.c @@ -15,10 +15,9 @@ void mock_glBufferData_(int, size_t, const void *, int); #define glfwInit mock_glfwInit_ #define hs_throw_error mock_hs_throw_error_ #define glfwTerminate mock_glfwTerminate_ -#undef glBufferData -#define glBufferData mock_glBufferData_ #define setup_shader DUMMY_FUNCTION #define setup_drawing DUMMY_FUNCTION +#define setup_texture DUMMY_FUNCTION #include "gl/gl.c" #include "gl/data.c" #undef glBufferData -- cgit v1.2.1 From c52e1b30391d730cd6d20f65ec75d61884355c5c Mon Sep 17 00:00:00 2001 From: sanine Date: Mon, 22 Aug 2022 23:58:00 -0500 Subject: refactor: rename opengl functions to match their C counterparts --- src/gl/data.c | 47 +++++++++++++++++++++++------------------------ src/gl/drawing.c | 39 +++++++++++++++++++-------------------- src/gl/gl.c | 44 +++++++++++++++++++++----------------------- src/gl/shader.c | 45 +++++++++++++++++++++++---------------------- src/gl/texture.c | 37 ++++++++++++++++++------------------- 5 files changed, 104 insertions(+), 108 deletions(-) (limited to 'src/gl') diff --git a/src/gl/data.c b/src/gl/data.c index 777689a..a9d0324 100644 --- a/src/gl/data.c +++ b/src/gl/data.c @@ -4,6 +4,7 @@ #include #include #include +#include "util/util.h" #include "gl.h" int gl_create_buffer(lua_State *L); @@ -18,32 +19,30 @@ int gl_vertex_array_enable_attrib(lua_State *L); void setup_data(lua_State *L, int gl_index) { - int buffer_binding_targets = hs_create_table(L, - hs_str_int("arrayBuffer", GL_ARRAY_BUFFER), - hs_str_int("elementArrayBuffer", GL_ELEMENT_ARRAY_BUFFER), - ); - - int buffer_usage_patterns = hs_create_table(L, - hs_str_int("streamDraw", GL_STREAM_DRAW), - hs_str_int("staticDraw", GL_STATIC_DRAW), - hs_str_int("dynamicDraw", GL_DYNAMIC_DRAW), - ); - - hs_create_table(L, - hs_str_cfunc("createBuffer", gl_create_buffer), - hs_str_cfunc("bindBuffer", gl_bind_buffer), - hs_str_cfunc("bufferData", gl_buffer_data), - - hs_str_cfunc("createVertexArray", gl_vertex_array_create), - hs_str_cfunc("bindVertexArray", gl_vertex_array_bind), - hs_str_cfunc("vertexAttribPointer", gl_vertex_attrib_pointer), - hs_str_cfunc("vertexArrayEnableAttrib", gl_vertex_array_enable_attrib), - - hs_str_tbl("bufferTarget", buffer_binding_targets), - hs_str_tbl("bufferUsage", buffer_usage_patterns), + int tbl = hs_create_table(L, + /* functions */ + hs_str_cfunc("GenBuffers", gl_create_buffer), + hs_str_cfunc("BindBuffer", gl_bind_buffer), + hs_str_cfunc("BufferData", gl_buffer_data), + + hs_str_cfunc("GenVertexArrays", gl_vertex_array_create), + hs_str_cfunc("BindVertexArray", gl_vertex_array_bind), + hs_str_cfunc("VertexAttribPointer", gl_vertex_attrib_pointer), + hs_str_cfunc("EnableVertexAttribArray", gl_vertex_array_enable_attrib), + + /******** enums ********/ + /* buffer bind targets */ + hs_str_int("ARRAY_BUFFER", GL_ARRAY_BUFFER), + hs_str_int("ELEMENT_ARRAY_BUFFER", GL_ELEMENT_ARRAY_BUFFER), + + /* buffer usage patters */ + hs_str_int("STREAM_DRAW", GL_STREAM_DRAW), + hs_str_int("STATIC_DRAW", GL_STATIC_DRAW), + hs_str_int("DYNAMIC_DRAW", GL_DYNAMIC_DRAW), ); - lua_setfield(L, gl_index, "data"); + append_table(L, gl_index, tbl); + lua_pop(L, 1); } diff --git a/src/gl/drawing.c b/src/gl/drawing.c index ca914e0..e6b1e13 100644 --- a/src/gl/drawing.c +++ b/src/gl/drawing.c @@ -2,6 +2,7 @@ #include #include #include +#include "util/util.h" int gl_set_viewport(lua_State *L); int gl_draw_arrays(lua_State *L); @@ -11,30 +12,28 @@ int gl_clear(lua_State *L); void setup_drawing(lua_State *L, int gl_index) { - int primitive_types = hs_create_table(L, - hs_str_int("points", GL_POINTS), - hs_str_int("lines", GL_LINES), - hs_str_int("triangles", GL_TRIANGLES), - ); - - int buffer_masks = hs_create_table(L, - hs_str_int("colorBuffer", GL_COLOR_BUFFER_BIT), - hs_str_int("depthBuffer", GL_DEPTH_BUFFER_BIT), - hs_str_int("stencilBuffer", GL_STENCIL_BUFFER_BIT), - ); + int tbl = hs_create_table(L, + /* functions */ + hs_str_cfunc("DrawArrays", gl_draw_arrays), + hs_str_cfunc("DrawElements", gl_draw_elements), + hs_str_cfunc("ClearColor", gl_set_clear_color), + hs_str_cfunc("Clear", gl_clear), + hs_str_cfunc("Viewport", gl_set_viewport), - hs_create_table(L, - hs_str_cfunc("drawArrays", gl_draw_arrays), - hs_str_cfunc("drawElements", gl_draw_elements), - hs_str_cfunc("setClearColor", gl_set_clear_color), - hs_str_cfunc("clear", gl_clear), - hs_str_cfunc("setViewport", gl_set_viewport), + /******** enums ********/ + /* rendering primitives */ + hs_str_int("POINTS", GL_POINTS), + hs_str_int("LINES", GL_LINES), + hs_str_int("TRIANGLES", GL_TRIANGLES), - hs_str_tbl("primitiveType", primitive_types), - hs_str_tbl("bufferMask", buffer_masks), + /* clear bitmasks */ + hs_str_int("COLOR_BUFFER_BIT", GL_COLOR_BUFFER_BIT), + hs_str_int("DEPTH_BUFFER_BIT", GL_DEPTH_BUFFER_BIT), + hs_str_int("STENCIL_BUFFER_BIT", GL_STENCIL_BUFFER_BIT), ); - lua_setfield(L, gl_index, "draw"); + append_table(L, gl_index, tbl); + lua_pop(L, 1); } int gl_set_clear_color(lua_State *L) diff --git a/src/gl/gl.c b/src/gl/gl.c index c4502dc..4639d48 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -20,36 +20,34 @@ int gl_get_error(lua_State *L); void setup_gl(lua_State *L, int honey_index) { - int data_types = hs_create_table(L, - hs_str_int("uchar", GL_UNSIGNED_BYTE), - hs_str_int("uint", GL_UNSIGNED_INT), - hs_str_int("int", GL_INT), - hs_str_int("float", GL_FLOAT), - ); - - int error_types = hs_create_table(L, - hs_str_int("noError", GL_NO_ERROR), - hs_str_int("invalidEnum", GL_INVALID_ENUM), - hs_str_int("invalidValue", GL_INVALID_VALUE), - hs_str_int("invalidOperation", GL_INVALID_OPERATION), - hs_str_int("invalidFramebufferOperation", GL_INVALID_FRAMEBUFFER_OPERATION), - hs_str_int("outOfMemory", GL_OUT_OF_MEMORY), - ); - int gl_index = hs_create_table(L, - hs_str_cfunc("init", gl_init), - hs_str_cfunc("initGlad", glad_init), - hs_str_cfunc("terminate", gl_terminate), - hs_str_cfunc("getError", gl_get_error), - - hs_str_tbl("dataType", data_types), - hs_str_tbl("errorType", error_types), + /* functions */ + hs_str_cfunc("Init", gl_init), + hs_str_cfunc("InitGlad", glad_init), + hs_str_cfunc("Terminate", gl_terminate), + hs_str_cfunc("GetError", gl_get_error), + + /******** enums ********/ + /* data types */ + hs_str_int("UNSIGNED_BYTE", GL_UNSIGNED_BYTE), + hs_str_int("UNSIGNED_INT", GL_UNSIGNED_INT), + hs_str_int("INT", GL_INT), + hs_str_int("FLOAT", GL_FLOAT), + + /* error types */ + hs_str_int("NO_ERROR", GL_NO_ERROR), + hs_str_int("INVALID_ENUM", GL_INVALID_ENUM), + hs_str_int("INVALID_VALUE", GL_INVALID_VALUE), + hs_str_int("INVALID_OPERATION", GL_INVALID_OPERATION), + hs_str_int("INVALID_FRAMEBUFFER_OPERATION", GL_INVALID_FRAMEBUFFER_OPERATION), + hs_str_int("OUT_OF_MEMORY", GL_OUT_OF_MEMORY), ); setup_shader(L, gl_index); setup_drawing(L, gl_index); setup_data(L, gl_index); setup_texture(L, gl_index); + lua_setfield(L, honey_index, "gl"); } diff --git a/src/gl/shader.c b/src/gl/shader.c index c3b409c..b4d03e6 100644 --- a/src/gl/shader.c +++ b/src/gl/shader.c @@ -2,6 +2,7 @@ #include #include #include +#include "util/util.h" int gl_create_shader(lua_State *L); int gl_shader_set_source(lua_State *L); @@ -20,30 +21,30 @@ int gl_uniform_4f(lua_State *L); void setup_shader(lua_State *L, int gl_index) { - int shader_types = hs_create_table(L, - hs_str_int("vertexShader", GL_VERTEX_SHADER), - hs_str_int("fragmentShader", GL_FRAGMENT_SHADER), + int tbl = hs_create_table(L, + /* functions */ + hs_str_cfunc("CreateShader", gl_create_shader), + hs_str_cfunc("ShaderSource", gl_shader_set_source), + hs_str_cfunc("CompileShader", gl_shader_compile), + hs_str_cfunc("DeleteShader", gl_shader_delete), + + hs_str_cfunc("CreateProgram", gl_program_create), + hs_str_cfunc("AttachShader", gl_program_attach_shader), + hs_str_cfunc("LinkProgram", gl_program_link), + hs_str_cfunc("UseProgram", gl_program_use), + + hs_str_cfunc("GetUniformLocation", gl_uniform_get_location), + hs_str_cfunc("Uniform1i", gl_uniform_1i), + hs_str_cfunc("Uniform4f", gl_uniform_4f), + + /******** enums ********/ + /* shader types */ + hs_str_int("VERTEX_SHADER", GL_VERTEX_SHADER), + hs_str_int("FRAGMENT_SHADER", GL_FRAGMENT_SHADER), ); - hs_create_table(L, - hs_str_cfunc("create", gl_create_shader), - hs_str_cfunc("setSource", gl_shader_set_source), - hs_str_cfunc("compile", gl_shader_compile), - hs_str_cfunc("delete", gl_shader_delete), - - hs_str_cfunc("createProgram", gl_program_create), - hs_str_cfunc("attachShader", gl_program_attach_shader), - hs_str_cfunc("link", gl_program_link), - hs_str_cfunc("use", gl_program_use), - - hs_str_cfunc("getUniformLocation", gl_uniform_get_location), - hs_str_cfunc("uniform1i", gl_uniform_1i), - hs_str_cfunc("uniform4f", gl_uniform_4f), - - hs_str_tbl("type", shader_types), - ); - - lua_setfield(L, gl_index, "shader"); + append_table(L, gl_index, tbl); + lua_pop(L, 1); } diff --git a/src/gl/texture.c b/src/gl/texture.c index d0c3a0a..739dd13 100644 --- a/src/gl/texture.c +++ b/src/gl/texture.c @@ -2,6 +2,7 @@ #include #include #include +#include "util/util.h" int gl_texture_create(lua_State *L); @@ -13,27 +14,25 @@ int gl_texture_set_active(lua_State *L); void setup_texture(lua_State *L, int gl_index) { - int bind_targets = hs_create_table(L, - hs_str_int("texture2d", GL_TEXTURE_2D), + int tbl = hs_create_table(L, + /* functions */ + hs_str_cfunc("GenTextures", gl_texture_create), + hs_str_cfunc("BindTexture", gl_texture_bind), + hs_str_cfunc("TexImage2D", gl_texture_image_2d), + hs_str_cfunc("GenerateMipmap", gl_texture_generate_mipmaps), + hs_str_cfunc("ActiveTexture", gl_texture_set_active), + + /******** enums ********/ + /* texture binding targets */ + hs_str_int("TEXTURE_2D", GL_TEXTURE_2D), + + /* texture data formats */ + hs_str_int("RGB", GL_RGB), + hs_str_int("RGBA", GL_RGBA), ); - int formats = hs_create_table(L, - hs_str_int("rgb", GL_RGB), - hs_str_int("rgba", GL_RGBA), - ); - - hs_create_table(L, - hs_str_cfunc("create", gl_texture_create), - hs_str_cfunc("bind", gl_texture_bind), - hs_str_cfunc("bufferImage2d", gl_texture_image_2d), - hs_str_cfunc("generateMipmaps", gl_texture_generate_mipmaps), - hs_str_cfunc("setActiveUnit", gl_texture_set_active), - - hs_str_tbl("bindTarget", bind_targets), - hs_str_tbl("format", formats), - ); - - lua_setfield(L, gl_index, "texture"); + append_table(L, gl_index, tbl); + lua_pop(L, 1); } -- cgit v1.2.1 From 711f530f7afe3358c674cf418ee067e7a4501699 Mon Sep 17 00:00:00 2001 From: sanine Date: Tue, 23 Aug 2022 00:31:14 -0500 Subject: add gl.TexParameteri() --- src/gl/texture.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/gl') diff --git a/src/gl/texture.c b/src/gl/texture.c index 739dd13..f9a65b3 100644 --- a/src/gl/texture.c +++ b/src/gl/texture.c @@ -10,6 +10,7 @@ int gl_texture_bind(lua_State *L); int gl_texture_image_2d(lua_State *L); int gl_texture_generate_mipmaps(lua_State *L); int gl_texture_set_active(lua_State *L); +int gl_tex_parameter_i(lua_State *L); void setup_texture(lua_State *L, int gl_index) @@ -21,6 +22,7 @@ void setup_texture(lua_State *L, int gl_index) hs_str_cfunc("TexImage2D", gl_texture_image_2d), hs_str_cfunc("GenerateMipmap", gl_texture_generate_mipmaps), hs_str_cfunc("ActiveTexture", gl_texture_set_active), + hs_str_cfunc("TexParameteri", gl_tex_parameter_i), /******** enums ********/ /* texture binding targets */ @@ -29,6 +31,19 @@ void setup_texture(lua_State *L, int gl_index) /* texture data formats */ hs_str_int("RGB", GL_RGB), hs_str_int("RGBA", GL_RGBA), + + /* texture parameters */ + hs_str_int("TEXTURE_WRAP_S", GL_TEXTURE_WRAP_S), + hs_str_int("TEXTURE_WRAP_T", GL_TEXTURE_WRAP_T), + hs_str_int("TEXTURE_MIN_FILTER", GL_TEXTURE_MIN_FILTER), + hs_str_int("TEXTURE_MAG_FILTER", GL_TEXTURE_MAG_FILTER), + + /* wrapping types */ + hs_str_int("REPEAT", GL_REPEAT), + + /* filter types */ + hs_str_int("NEAREST", GL_NEAREST), + hs_str_int("LINEAR", GL_LINEAR), ); append_table(L, gl_index, tbl); @@ -90,3 +105,12 @@ int gl_texture_set_active(lua_State *L) glActiveTexture(GL_TEXTURE0 + unit); return 0; } + + +int gl_tex_parameter_i(lua_State *L) +{ + lua_Integer target, pname, param; + hs_parse_args(L, hs_int(target), hs_int(pname), hs_int(param)); + glTexParameteri(target, pname, param); + return 0; +} -- cgit v1.2.1 From ae4e17fc743ca0344af818ab767db7311ea7829c Mon Sep 17 00:00:00 2001 From: sanine Date: Tue, 23 Aug 2022 13:28:01 -0500 Subject: add basic transforms --- src/gl/shader.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src/gl') diff --git a/src/gl/shader.c b/src/gl/shader.c index b4d03e6..3732aff 100644 --- a/src/gl/shader.c +++ b/src/gl/shader.c @@ -18,6 +18,8 @@ int gl_uniform_get_location(lua_State *L); int gl_uniform_1i(lua_State *L); int gl_uniform_4f(lua_State *L); +int gl_uniform_matrix_4fv(lua_State *L); + void setup_shader(lua_State *L, int gl_index) { @@ -37,6 +39,8 @@ void setup_shader(lua_State *L, int gl_index) hs_str_cfunc("Uniform1i", gl_uniform_1i), hs_str_cfunc("Uniform4f", gl_uniform_4f), + hs_str_cfunc("UniformMatrix4fv", gl_uniform_matrix_4fv), + /******** enums ********/ /* shader types */ hs_str_int("VERTEX_SHADER", GL_VERTEX_SHADER), @@ -63,7 +67,7 @@ int gl_shader_set_source(lua_State *L) lua_Integer shader; char *code; hs_parse_args(L, hs_int(shader), hs_str(code)); - glShaderSource(shader, 1, &code, NULL); + glShaderSource(shader, 1, (const GLchar * const*)&code, NULL); return 0; } @@ -161,3 +165,16 @@ int gl_uniform_4f(lua_State *L) glUniform4f(location, v0, v1, v2, v3); return 0; } + + +int gl_uniform_matrix_4fv(lua_State *L) +{ + lua_Integer location; + bool transpose; + void *ptr; + hs_parse_args(L, hs_int(location), hs_bool(transpose), hs_user(ptr)); + + float *value = ptr; + glUniformMatrix4fv(location, 1, transpose, value); + return 0; +} -- cgit v1.2.1 From 25ed7eb9f84e9a822f698ad803901fbb2a5354cf Mon Sep 17 00:00:00 2001 From: sanine Date: Tue, 23 Aug 2022 13:28:11 -0500 Subject: fix memory leak --- src/gl/window.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gl') diff --git a/src/gl/window.c b/src/gl/window.c index 1b8c4bb..fd13022 100644 --- a/src/gl/window.c +++ b/src/gl/window.c @@ -98,6 +98,11 @@ 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; } -- cgit v1.2.1