summaryrefslogtreecommitdiff
path: root/src/shader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader.c')
-rw-r--r--src/shader.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/shader.c b/src/shader.c
new file mode 100644
index 0000000..6ced034
--- /dev/null
+++ b/src/shader.c
@@ -0,0 +1,194 @@
+#include "shader.h"
+
+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);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_shader_new(lua_State* L)
+{
+ char* vertex_shader_source, *fragment_shader_source;
+ honey_lua_parse_arguments
+ (L, 1,
+ 2, HONEY_STRING, &vertex_shader_source, HONEY_STRING, &fragment_shader_source);
+
+ int success;
+ char error[1024];
+
+ int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vertex_shader, 1,
+ &vertex_shader_source, NULL);
+ glCompileShader(vertex_shader);
+ glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
+ if (!success) {
+ glGetShaderInfoLog(vertex_shader, 1024, NULL, error);
+ honey_lua_throw_error(L, "error compiling vertex shader: %s",
+ error);
+ }
+
+ int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fragment_shader, 1,
+ &fragment_shader_source, NULL);
+ glCompileShader(fragment_shader);
+ glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
+ if (!success) {
+ glGetShaderInfoLog(fragment_shader, 1024, NULL, error);
+ honey_lua_throw_error(L, "error compiling fragment shader: %s",
+ error);
+ }
+
+ int shader = glCreateProgram();
+ glAttachShader(shader, vertex_shader);
+ glAttachShader(shader, fragment_shader);
+ glLinkProgram(shader);
+
+ glGetShaderiv(shader, GL_LINK_STATUS, &success);
+ if (!success) {
+ glGetShaderInfoLog(shader, 1024, NULL, error);
+ honey_lua_throw_error(L, "error linking shader program: %s",
+ error);
+ }
+
+ glDeleteShader(vertex_shader);
+ glDeleteShader(fragment_shader);
+
+ lua_pushinteger(L, shader);
+ return 1;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_shader_use(lua_State* L)
+{
+ int shader;
+ honey_lua_parse_arguments
+ (L, 1,
+ 1, HONEY_INTEGER, &shader);
+
+ glUseProgram(shader);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_shader_set_int(lua_State* L)
+{
+ int shader, value;
+ char* name;
+
+ honey_lua_parse_arguments
+ (L, 1,
+ 3,
+ HONEY_INTEGER, &shader,
+ HONEY_STRING, &name,
+ HONEY_INTEGER, &value);
+
+ glUseProgram(shader);
+ unsigned int location = glGetUniformLocation(shader, name);
+ glUniform1i(location, value);
+
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_shader_set_float(lua_State* L)
+{
+ int shader; char* name; float value;
+ honey_lua_parse_arguments
+ (L, 1, 3,
+ HONEY_INTEGER, &shader,
+ HONEY_STRING, &name,
+ HONEY_NUMBER, &value);
+
+ glUseProgram(shader);
+ unsigned int location = glGetUniformLocation(shader, name);
+ glUniform1f(location, value);
+
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_shader_set_vec3(lua_State* L)
+{
+ int shader; char* name; float* array;
+ honey_lua_parse_arguments
+ (L, 1, 3,
+ HONEY_INTEGER, &shader,
+ HONEY_STRING, &name,
+ HONEY_USERDATA, &array);
+
+
+ unsigned int location;
+ float* array;
+ get_array(L, &location, &array);
+
+ glUniform3fv(location, 1, array);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_shader_set_vec4(lua_State* L)
+{
+ unsigned int location;
+ float* array;
+ get_array(L, &location, &array);
+
+ glUniform4fv(location, 1, array);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_shader_set_mat3(lua_State* L)
+{
+ unsigned int location;
+ float* array;
+ get_array(L, &location, &array);
+
+ glUniformMatrix3fv(location, 1, GL_FALSE, array);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_shader_set_mat4(lua_State* L)
+{
+ unsigned int location;
+ float* array;
+ get_array(L, &location, &array);
+
+ glUniformMatrix4fv(location, 1, GL_FALSE, array);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+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);
+
+ glDeleteProgram(shader);
+ return 0;
+}