diff options
author | sanine-a <sanine.not@pm.me> | 2020-10-19 05:35:06 -0500 |
---|---|---|
committer | sanine-a <sanine.not@pm.me> | 2020-10-19 05:35:06 -0500 |
commit | 41fa908dc15b522e53946a716f4f6c00520bd46f (patch) | |
tree | bc8176462000b2c77c00d3227037c1acbb13e0ee /src/shader/shader.c | |
parent | 2d046ffd16d8ff3a06f92ca438ca6b2d6842ce6a (diff) |
add honey libraries back and reorganize directories
Diffstat (limited to 'src/shader/shader.c')
-rw-r--r-- | src/shader/shader.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/shader/shader.c b/src/shader/shader.c new file mode 100644 index 0000000..817d451 --- /dev/null +++ b/src/shader/shader.c @@ -0,0 +1,224 @@ +#include "shader.h" + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +static honey_result read_file(char** destination, char* file_path) { + FILE* f = fopen(file_path, "r"); + if (f == NULL) { + honey_error_set_string1(file_path); + return HONEY_FILE_READ_ERROR; + } + + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + *destination = malloc(fsize + 1); + if (*destination == NULL) { + return HONEY_MEMORY_ALLOCATION_ERROR; + } + fread(*destination, 1, fsize, f); + fclose(f); + + (*destination)[fsize] = 0; + + return HONEY_OK; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +honey_result honey_shader_load(honey_shader* shader, + char* vertex_shader_path, + char* fragment_shader_path) { + /* load vertex shader code */ + char* vertex_shader_code; + honey_result result = read_file(&vertex_shader_code, + vertex_shader_path); + if (result != HONEY_OK) + return result; + + /* load fragment shader code */ + char* fragment_shader_code; + result = read_file(&fragment_shader_code, + fragment_shader_path); + if (result != HONEY_OK) + return result; + + result = honey_shader_new(shader, + vertex_shader_code, + fragment_shader_code); + + if (result == HONEY_VERTEX_SHADER_COMPILATION_ERROR) + honey_error_set_string2(vertex_shader_path); + + if (result == HONEY_FRAGMENT_SHADER_COMPILATION_ERROR) + honey_error_set_string2(fragment_shader_path); + + free(vertex_shader_code); + free(fragment_shader_code); + + return result; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +honey_result honey_shader_new(honey_shader* shader, + char* vertex_shader_code, + char* fragment_shader_code) { + /* compile shaders */ + int success; + char error[512]; + + int vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, ((const char**)&vertex_shader_code), NULL); + glCompileShader(vertex_shader); + glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); + if (!success) { + honey_error_clear_strings(); + char compiler_error[HONEY_ERROR_DATA_STRING_LENGTH]; + glGetShaderInfoLog(vertex_shader, HONEY_ERROR_DATA_STRING_LENGTH, NULL, compiler_error); + honey_error_set_string1(compiler_error); + return HONEY_VERTEX_SHADER_COMPILATION_ERROR; + } + + int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, ((const char**)&fragment_shader_code), NULL); + glCompileShader(fragment_shader); + glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success); + if (!success) { + honey_error_clear_strings(); + char compiler_error[HONEY_ERROR_DATA_STRING_LENGTH]; + glGetShaderInfoLog(fragment_shader, HONEY_ERROR_DATA_STRING_LENGTH, NULL, compiler_error); + honey_error_set_string1(compiler_error); + return HONEY_FRAGMENT_SHADER_COMPILATION_ERROR; + } + + /* link shaders */ + *shader = glCreateProgram(); + glAttachShader(*shader, vertex_shader); + glAttachShader(*shader, fragment_shader); + glLinkProgram(*shader); + glGetShaderiv(*shader, GL_LINK_STATUS, &success); + if (!success) { + honey_error_clear_strings(); + char compiler_error[HONEY_ERROR_DATA_STRING_LENGTH]; + glGetShaderInfoLog(vertex_shader, HONEY_ERROR_DATA_STRING_LENGTH, NULL, compiler_error); + honey_error_set_string1(compiler_error); + return HONEY_SHADER_LINK_ERROR; + } + + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + + return HONEY_OK; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_shader_set_int(honey_shader shader, + char* int_name, + int value) { + honey_shader_use(shader); + unsigned int int_location = glGetUniformLocation(shader, int_name); + glUniform1i(int_location, value); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_shader_set_float(honey_shader shader, + char* float_name, + float value) { + honey_shader_use(shader); + unsigned int float_location = glGetUniformLocation(shader, float_name); + glUniform1f(float_location, value); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_shader_set_vec3(honey_shader shader, + char* vector_name, + vec3 value) { + honey_shader_use(shader); + unsigned int vector_location = glGetUniformLocation(shader, vector_name); + glUniform3fv(vector_location, 1, (float*) value); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_shader_set_mat3(honey_shader shader, + char* matrix_name, + mat3 value) { + glUseProgram(shader); + unsigned int matrix_location = glGetUniformLocation(shader, matrix_name); + glUniformMatrix3fv(matrix_location, 1, GL_FALSE, (float*) value); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_shader_set_mat4(honey_shader shader, + char* matrix_name, + mat4 value) { + glUseProgram(shader); + unsigned int matrix_location = glGetUniformLocation(shader, matrix_name); + glUniformMatrix4fv(matrix_location, 1, GL_FALSE, (float*) value); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_shader_set_point_light(honey_shader shader, + int point_light_index, + honey_point_light light) { + char name[HONEY_MAX_LIGHT_NAME_LENGTH]; + + snprintf(name, + HONEY_MAX_LIGHT_NAME_LENGTH, + "point_lights[%d].position", + point_light_index); + honey_shader_set_vec3(shader, name, light.position); + + snprintf(name, + HONEY_MAX_LIGHT_NAME_LENGTH, + "point_lights[%d].color", + point_light_index); + honey_shader_set_vec3(shader, name, light.color); + + snprintf(name, + HONEY_MAX_LIGHT_NAME_LENGTH, + "point_lights[%d].constant", + point_light_index); + honey_shader_set_float(shader, name, light.constant); + + snprintf(name, + HONEY_MAX_LIGHT_NAME_LENGTH, + "point_lights[%d].linear", + point_light_index); + honey_shader_set_float(shader, name, light.linear); + + snprintf(name, + HONEY_MAX_LIGHT_NAME_LENGTH, + "point_lights[%d].quadratic", + point_light_index); + honey_shader_set_float(shader, name, light.quadratic); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_shader_set_directional_light(honey_shader shader, + int directional_light_index, + honey_directional_light light) { + char name[HONEY_MAX_LIGHT_NAME_LENGTH]; + + snprintf(name, + HONEY_MAX_LIGHT_NAME_LENGTH, + "directional_lights[%d].direction", + directional_light_index); + honey_shader_set_vec3(shader, name, light.direction); + + snprintf(name, + HONEY_MAX_LIGHT_NAME_LENGTH, + "directional_lights[%d].color", + directional_light_index); + honey_shader_set_vec3(shader, name, light.color); +} + + |