diff options
Diffstat (limited to 'src/shader.c')
-rw-r--r-- | src/shader.c | 194 |
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; +} |