diff options
Diffstat (limited to 'src/gl')
-rw-r--r-- | src/gl/gl.c | 65 | ||||
-rw-r--r-- | src/gl/gl.test.c | 68 |
2 files changed, 130 insertions, 3 deletions
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 <stdlib.h> #include "gl/glad/glad.h" #include <GLFW/glfw3.h> #include <lua.h> #include <honeysuckle.h> +/* 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; i<len; i++) { + lua_rawgeti(L, table, i+1); + if (!lua_isnumber(L, -1)) { + hs_throw_error(L, "all table items must be numbers (failed at index %d)", i); + } + buf[i] = lua_tonumber(L, -1); + lua_pop(L, 1); + } + + /* call */ + glBufferData(target, len*sizeof(lua_Number), buf, usage); + free(buf); + return 0; +} diff --git a/src/gl/gl.test.c b/src/gl/gl.test.c index 9bacbf9..aa24fd2 100644 --- a/src/gl/gl.test.c +++ b/src/gl/gl.test.c @@ -6,13 +6,17 @@ int mock_glfwInit_(void); -int mock_hs_throw_error_(lua_State *L, const char *str); +int mock_hs_throw_error_(lua_State *L, const char *str, ...); void mock_glfwTerminate_(); +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_ #include "gl/gl.c" +#undef glBufferData #undef glfwTerminate #undef hs_throw_error #undef glfwInit @@ -31,7 +35,7 @@ int mock_glfwInit_() lily_mock_t *mock_hs_throw_error = NULL; -int mock_hs_throw_error_(lua_State *L, const char *str) +int mock_hs_throw_error_(lua_State *L, const char *str, ...) { struct lily_mock_arg_t args[] = { { sizeof(const char *), &str } @@ -53,6 +57,24 @@ void mock_glfwTerminate_() } +lily_mock_t *mock_glBufferData = NULL; +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); + + size_t count = size/sizeof(lua_Number); + lua_Number *numbers = data; + for (int i=0; i<count; i++) { + lily_store_value(mock_glBufferData, lua_Number, numbers[i]); + } +} + + /* ~~~~~~~~ suite ~~~~~~~~ */ void gl_init_succeeds() @@ -102,13 +124,55 @@ void gl_terminate_works() } +void gl_buffer_data_works() +{ + lily_mock_use(&mock_hs_throw_error); + lily_mock_use(&mock_glBufferData); + + lua_State *L = luaL_newstate(); + lua_pushcfunction(L, gl_buffer_data); + lua_pushinteger(L, GL_ARRAY_BUFFER); + 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, 3, 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(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); } |