From f9f3ab244d12e6c7f38bf56dcf22c6a4913dc0f6 Mon Sep 17 00:00:00 2001 From: sanine-a Date: Sun, 29 Nov 2020 16:03:40 -0600 Subject: refactor: make shader a full lua object with __gc metamethod --- src/shader.c | 159 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 106 insertions(+), 53 deletions(-) (limited to 'src/shader.c') diff --git a/src/shader.c b/src/shader.c index 6ced034..6e393c2 100644 --- a/src/shader.c +++ b/src/shader.c @@ -4,19 +4,25 @@ int honey_shader_mt_ref = LUA_NOREF; void honey_setup_shader(lua_State* L) { - honey_lua_element shader_elements[] = { - { "new", HONEY_FUNCTION, { .function = honey_shader_new } }, - { "use", HONEY_FUNCTION, { .function = honey_shader_use } }, - { "set_int", HONEY_FUNCTION, { .function = honey_shader_set_int } }, - { "set_float", HONEY_FUNCTION, { .function = honey_shader_set_float } }, - { "set_vec3", HONEY_FUNCTION, { .function = honey_shader_set_vec3 } }, - { "set_vec4", HONEY_FUNCTION, { .function = honey_shader_set_vec4 } }, - { "set_mat3", HONEY_FUNCTION, { .function = honey_shader_set_mat3 } }, - { "set_mat4", HONEY_FUNCTION, { .function = honey_shader_set_mat4 } }, - { "delete", HONEY_FUNCTION, { .function = honey_shader_delete } }, - }; - - honey_lua_create_table(L, shader_elements, 9); + honey_lua_create_table + (L, 2, + HONEY_TABLE, "__index", 7, + + /* honey.shader.prototype */ + HONEY_FUNCTION, "use", honey_shader_use, + HONEY_FUNCTION, "set_int", honey_shader_set_int, + HONEY_FUNCTION, "set_float", honey_shader_set_float, + HONEY_FUNCTION, "set_vec3", honey_shader_set_vec3, + HONEY_FUNCTION, "set_vec4", honey_shader_set_vec4, + HONEY_FUNCTION, "set_mat3", honey_shader_set_mat3, + HONEY_FUNCTION, "set_mat4", honey_shader_set_mat4, + + HONEY_FUNCTION, "__gc", honey_shader_delete); + + honey_shader_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX); + + lua_pushcfunction(L, honey_shader_new); + lua_setfield(L, -2, "shader"); } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -33,7 +39,7 @@ int honey_shader_new(lua_State* L) int vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, - &vertex_shader_source, NULL); + (const char* const*) &vertex_shader_source, NULL); glCompileShader(vertex_shader); glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); if (!success) { @@ -44,7 +50,7 @@ int honey_shader_new(lua_State* L) int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, - &fragment_shader_source, NULL); + (const char* const*) &fragment_shader_source, NULL); glCompileShader(fragment_shader); glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success); if (!success) { @@ -53,7 +59,7 @@ int honey_shader_new(lua_State* L) error); } - int shader = glCreateProgram(); + int program = glCreateProgram(); glAttachShader(shader, vertex_shader); glAttachShader(shader, fragment_shader); glLinkProgram(shader); @@ -68,7 +74,17 @@ int honey_shader_new(lua_State* L) glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); - lua_pushinteger(L, shader); + int* shader = lua_newuserdata(L, sizeof(int)); + *shader = program; + + if (honey_shader_mt_ref == LUA_NOREF || + honey_shader_mt_ref == LUA_REFNIL) + honey_lua_throw_error + (L, "cannot create shader as there is no shader metatable set up."); + + lua_rawgeti(L, LUA_REGISTRYINDEX, honey_shader_mt_ref); + lua_setmetatable(L, -2); + return 1; } @@ -76,12 +92,12 @@ int honey_shader_new(lua_State* L) int honey_shader_use(lua_State* L) { - int shader; + int *shader; honey_lua_parse_arguments (L, 1, - 1, HONEY_INTEGER, &shader); + 1, HONEY_USERDATA, &shader); - glUseProgram(shader); + glUseProgram(*shader); return 0; } @@ -89,18 +105,18 @@ int honey_shader_use(lua_State* L) int honey_shader_set_int(lua_State* L) { - int shader, value; + int *shader, value; char* name; honey_lua_parse_arguments (L, 1, 3, - HONEY_INTEGER, &shader, + HONEY_USERDATA, &shader, HONEY_STRING, &name, HONEY_INTEGER, &value); - glUseProgram(shader); - unsigned int location = glGetUniformLocation(shader, name); + glUseProgram(*shader); + unsigned int location = glGetUniformLocation(*shader, name); glUniform1i(location, value); return 0; @@ -110,15 +126,15 @@ int honey_shader_set_int(lua_State* L) int honey_shader_set_float(lua_State* L) { - int shader; char* name; float value; + int *shader; char* name; float value; honey_lua_parse_arguments (L, 1, 3, - HONEY_INTEGER, &shader, + HONEY_USERDATA, &shader, HONEY_STRING, &name, HONEY_NUMBER, &value); - glUseProgram(shader); - unsigned int location = glGetUniformLocation(shader, name); + glUseProgram(*shader); + unsigned int location = glGetUniformLocation(*shader, name); glUniform1f(location, value); return 0; @@ -128,19 +144,22 @@ int honey_shader_set_float(lua_State* L) int honey_shader_set_vec3(lua_State* L) { - int shader; char* name; float* array; + int *shader; char* name; honey_glm_array* array; honey_lua_parse_arguments (L, 1, 3, - HONEY_INTEGER, &shader, + HONEY_USERDATA, &shader, HONEY_STRING, &name, HONEY_USERDATA, &array); - - - unsigned int location; - float* array; - get_array(L, &location, &array); - glUniform3fv(location, 1, array); + if (array->type != VEC3) + honey_lua_throw_error(L, + "expected glm array of type VEC3 (%d), but got %d instead", + VEC3, + array->type); + + glUseProgram(*shader); + unsigned int location = glGetUniformLocation(*shader, name); + glUniform3fv(location, 1, array->data); return 0; } @@ -148,11 +167,22 @@ int honey_shader_set_vec3(lua_State* L) int honey_shader_set_vec4(lua_State* L) { - unsigned int location; - float* array; - get_array(L, &location, &array); + int *shader; char* name; honey_glm_array* array; + honey_lua_parse_arguments + (L, 1, 3, + HONEY_USERDATA, &shader, + HONEY_STRING, &name, + HONEY_USERDATA, &array); - glUniform4fv(location, 1, array); + if (array->type != VEC4) + honey_lua_throw_error(L, + "expected glm array of type VEC4 (%d), but got %d instead", + VEC4, + array->type); + + glUseProgram(*shader); + unsigned int location = glGetUniformLocation(*shader, name); + glUniform4fv(location, 1, array->data); return 0; } @@ -160,11 +190,23 @@ int honey_shader_set_vec4(lua_State* L) int honey_shader_set_mat3(lua_State* L) { - unsigned int location; - float* array; - get_array(L, &location, &array); + int *shader; char* name; honey_glm_array* array; + honey_lua_parse_arguments + (L, 1, 3, + HONEY_USERDATA, &shader, + HONEY_STRING, &name, + HONEY_USERDATA, &array); + - glUniformMatrix3fv(location, 1, GL_FALSE, array); + if (array->type != MAT3) + honey_lua_throw_error(L, + "expected glm array of type MAT3 (%d), but got %d instead", + MAT3, + array->type); + + glUseProgram(*shader); + unsigned int location = glGetUniformLocation(*shader, name); + glUniformMatrix3fv(location, 1, GL_FALSE, array->data); return 0; } @@ -172,11 +214,23 @@ int honey_shader_set_mat3(lua_State* L) int honey_shader_set_mat4(lua_State* L) { - unsigned int location; - float* array; - get_array(L, &location, &array); + int *shader; char* name; float* array; + honey_lua_parse_arguments + (L, 1, 3, + HONEY_USERDATA, &shader, + HONEY_STRING, &name, + HONEY_USERDATA, &array); + - glUniformMatrix4fv(location, 1, GL_FALSE, array); + if (array->type != MAT4) + honey_lua_throw_error(L, + "expected glm array of type MAT4 (%d), but got %d instead", + MAT4, + array->type); + + glUseProgram(*shader); + unsigned int location = glGetUniformLocation(*shader, name); + glUniformMatrix4fv(location, 1, GL_FALSE, array->data); return 0; } @@ -184,11 +238,10 @@ int honey_shader_set_mat4(lua_State* L) int honey_shader_delete(lua_State* L) { - if (!honey_lua_validate_types(L, 1, HONEY_INTEGER)) - lua_error(L); - - int shader = lua_tointeger(L, 1); + int *shader; + honey_lua_parse_arguments + (L, 1, 1, HONEY_USERDATA, &shader); - glDeleteProgram(shader); + glDeleteProgram(*shader); return 0; } -- cgit v1.2.1