summaryrefslogtreecommitdiff
path: root/src/shader.c
diff options
context:
space:
mode:
authorsanine-a <sanine.not@pm.me>2020-11-29 16:03:40 -0600
committersanine-a <sanine.not@pm.me>2020-11-29 16:03:40 -0600
commitf9f3ab244d12e6c7f38bf56dcf22c6a4913dc0f6 (patch)
treea5fd617fb1d1fb511671326f68a8cc36775c708f /src/shader.c
parent140666204191b218b72274d8d14921c89a6631fd (diff)
refactor: make shader a full lua object with __gc metamethod
Diffstat (limited to 'src/shader.c')
-rw-r--r--src/shader.c159
1 files changed, 106 insertions, 53 deletions
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;
}