summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-08-19 00:39:04 -0500
committersanine <sanine.not@pm.me>2022-08-19 00:39:04 -0500
commitecde0c8110da1c1f94cce7f6a1fa9406d04eca69 (patch)
tree670e3d8706c652c1ffbf4f6406098af25a569c8b
parent275536b36657744d802866c060654e2b5cd5a5f8 (diff)
add several buffer-related functions
-rw-r--r--CMakeLists.txt4
-rw-r--r--src/gl/gl.c65
-rw-r--r--src/gl/gl.test.c68
3 files changed, 133 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 99964c3..2da7f20 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,6 +29,7 @@ add_subdirectory(${LIB_ROOT}/cglm)
set(HONEY_LIB_FILES
${SRC_ROOT}/logging/logging.c
+ ${SRC_ROOT}/gl/glad/glad.c
${SRC_ROOT}/gl/gl.c
${SRC_ROOT}/gl/window.c
)
@@ -59,6 +60,7 @@ set(TEST_SOURCES
${SRC_ROOT}/test/honey-test.c
${SRC_ROOT}/logging/logging.test.c
+ ${SRC_ROOT}/gl/glad/glad.c
${SRC_ROOT}/gl/gl.test.c
)
@@ -66,4 +68,4 @@ add_executable(test EXCLUDE_FROM_ALL ${TEST_SOURCES})
set_target_properties(test PROPERTIES
C_STANDARD 99
CMAKE_C_FLAGS "-Wall -Wextra -Werror -Wfatal-errors -Wpedantic")
-target_link_libraries(test lua5.1 honeysuckle)
+target_link_libraries(test lua5.1 honeysuckle dl)
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);
}