diff options
| author | sanine-a <sanine.not@pm.me> | 2020-10-25 19:37:42 -0500 | 
|---|---|---|
| committer | sanine-a <sanine.not@pm.me> | 2020-10-25 19:37:42 -0500 | 
| commit | acc262b019206d09ce0d297f7b185862fe432601 (patch) | |
| tree | 63071a346da01949966d217ed2d308b4ee21b197 /src/shader | |
| parent | c6f43d9254a82fcebcda4bcf0e692ff859ba8101 (diff) | |
remove model/* and add shader bindings
Diffstat (limited to 'src/shader')
| -rw-r--r-- | src/shader/shader.c | 350 | ||||
| -rw-r--r-- | src/shader/shader.h | 137 | 
2 files changed, 231 insertions, 256 deletions
| diff --git a/src/shader/shader.c b/src/shader/shader.c index 817d451..3deb5b8 100644 --- a/src/shader/shader.c +++ b/src/shader/shader.c @@ -1,224 +1,216 @@  #include "shader.h" +void honey_setup_shader(lua_State* L) +{ +    honey_lua_element shader_elements[] = { +        { "new", HONEY_FUNC, { .function = honey_shader_new } }, +        { "use", HONEY_FUNC, { .function = honey_shader_use } }, +        { "set_int", HONEY_FUNC, { .function = honey_shader_set_int } }, +        { "set_float", HONEY_FUNC, { .function = honey_shader_set_float } }, +        { "set_vec3", HONEY_FUNC, { .function = honey_shader_set_vec3 } }, +        { "set_vec4", HONEY_FUNC, { .function = honey_shader_set_vec4 } }, +        { "set_mat3", HONEY_FUNC, { .function = honey_shader_set_mat3 } }, +        { "set_mat4", HONEY_FUNC, { .function = honey_shader_set_mat4 } }, +        { "delete", HONEY_FUNC, { .function = honey_shader_delete } }, +    }; + +    honey_lua_create_table(L, shader_elements, 9); +} +  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -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; -  } +static bool compile_shader(int* shader, +                           const char* source, +                           int shader_type, +                           char* error_message, +                           size_t error_size) +{ +    int success; +     +    *shader = glCreateShader(GL_VERTEX_SHADER); +    glShaderSource(*shader, 1, source, NULL); +    glCompileShader(*shader); +    glGetShaderiv(*shader, GL_COMPILE_STATUS, &success); +    if (!success) { +        glGetShaderInfoLog(*shader, error_size, NULL, error_message); +        return false; +    } + +    return true; +} -  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); +int honey_shader_new(lua_State* L) +{ +    if (!honey_lua_validate_types(L, 2, HONEY_STRING, HONEY_STRING)) +        lua_error(L); -  (*destination)[fsize] = 0; +    const char* vertex_shader_source = lua_tostring(L, 1); +    const char* fragment_shader_source = lua_tostring(L, 2); +     +    char error[1024]; -  return HONEY_OK; +    int vertex_shader, fragment_shader; +     +    if (!compile_shader(&vertex_shader, +                        vertex_shader_source, +                        GL_VERTEX_SHADER, +                        error, 1024)) { +        lua_pushstring(L, error); +        lua_error(L); +    } + +    if (!compile_shader(&fragment_shader, +                        fragment_shader_source, +                        GL_FRAGMENT_SHADER, +                        error, 1024)) { +        lua_pushstring(L, error); +        lua_error(L); +    } + +    int shader = glCreateProgram(); +    glAttachShader(shader, vertex_shader); +    glAttachShader(shader, fragment_shader); +    glLinkProgram(shader); + +    int success; +    glGetShaderiv(shader, GL_LINK_STATUS, &success); +    if (!success) { +        glGetShaderInfoLog(shader, 1024, NULL, error); +        lua_pushstring(L, error); +        lua_error(L); +    } + +    glDeleteShader(vertex_shader); +    glDeleteShader(fragment_shader); + +    lua_pushinteger(L, shader); +    return 1;  }  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -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; +int honey_shader_use(lua_State* L) +{ +    if (!honey_lua_validate_types(L, 1, HONEY_INT)) +        lua_error(L); + +    int shader = lua_tointeger(L, 1); +    glUseProgram(shader); +    return 0;  }  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -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; +int honey_shader_set_int(lua_State* L) +{ +    if (!honey_lua_validate_types(L, 2, HONEY_INT, HONEY_STRING, HONEY_INT)) +        lua_error(L); + +    int shader       = lua_tointeger(L, 1); +    const char* name = lua_tostring(L, 2); +    int value        = lua_tointeger(L, 3); + +    glUseProgram(shader); +    unsigned int location = glGetUniformLocation(shader, name); +    glUniform1i(location, value); + +    return 0;  }  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -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); +int honey_shader_set_float(lua_State* L) +{ +    if (!honey_lua_validate_types(L, 2, HONEY_INT, HONEY_STRING, HONEY_NUM)) +        lua_error(L); + +    int shader       = lua_tointeger(L, 1); +    const char* name = lua_tostring(L, 2); +    float value      = lua_tonumber(L, 3); + +    glUseProgram(shader); +    unsigned int location = glGetUniformLocation(shader, name); +    glUniform1f(location, value); + +    return 0;  }  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -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); +static void get_array(lua_State* L, +                      unsigned int* location, +                      float** value) +{ +    if (!honey_lua_validate_types(L, 2, HONEY_INT, HONEY_STRING, HONEY_USERDATA)) +        lua_error(L); + +    int shader       = lua_tointeger(L, 1); +    const char* name = lua_tostring(L, 2); +    *value           = lua_touserdata(L, 3); + +    glUseProgram(shader); +    *location = glGetUniformLocation(shader, name);  }  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -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); +int honey_shader_set_vec3(lua_State* L) +{ +    unsigned int location; +    float* array; +    get_array(L, &location, &array); + +    glUniform3fv(location, 1, array); +    return 0;  }  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -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); +int honey_shader_set_vec4(lua_State* L) +{ +    unsigned int location; +    float* array; +    get_array(L, &location, &array); + +    glUniform4fv(location, 1, array); +    return 0;  }  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -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); +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;  }  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -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); +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;  }  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -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); -} +int honey_shader_delete(lua_State* L) +{ +    if (!honey_lua_validate_types(L, 1, HONEY_INT)) +        lua_error(L); + +    int shader = lua_tointeger(L, 1); -   +    glDeleteProgram(shader); +    return 0; +} diff --git a/src/shader/shader.h b/src/shader/shader.h index 07cc22d..95956ea 100644 --- a/src/shader/shader.h +++ b/src/shader/shader.h @@ -7,111 +7,94 @@  #define HONEY_SHADER_H  #include "../common.h" -#include "../light/light.h" -typedef int honey_shader; +/** @brief Push the shader table to the lua stack. + */ +void honey_setup_shader(lua_State* L); -/** @brief Load a shader. +/** @brief Create a new shader from source.   * - * @param[out] shader Pointer to the shader destination + * @param[in] vertex_source The GLSL code for the vertex shader. + * @param[in] fragment_source The GLSL code for the fragment shader.   * - * @param[in] vertex_shader_path The path to the vertex shader source code - * @param[in] fragment_shader_path The path to the fragment shader source code - *  - * @return The result of the shader load. + * @returns OpenGL handle for the compiled shader.   */ -honey_result honey_shader_load(honey_shader* shader, -                              char* vertex_shader_path, -                              char* fragment_shader_path); +int honey_shader_new(lua_State* L); -/** @brief Create a shader from code strings. +/** @brief Set a shader as the current OpenGL shader.   * - * @param[out] shader Pointer to the shader destination. - * @param[in] vertex_shader_code Zero-terminated string containing the vertex shader code to compile - * @param[in] fragment_shader_code Zero-terminated string containing the fragment shader code to compile + * @param[in] shader The OpenGL handle to a shader, as generated by honey.shader.new   * - * @return The result of the shader creation. + * @returns Nothing.   */ -honey_result honey_shader_new(honey_shader* shader, -                             char* vertex_shader_code, -                             char* fragment_shader_code); +int honey_shader_use(lua_State* L); -/** @brief Set an integer uniform. +/** @brief Set an integer uniform on a shader.   * - * @param[in] shader The shader to which the uniform belongs - * @param[in] int_name The name of the integer uniform - * @param[in] value The value of the integer uniform - */ -void honey_shader_set_int(honey_shader shader, -                          char* int_name, -                          int value); - -/** @brief Set a float uniform. + * @param[in] shader The OpenGL shader handle. + * @param[in] name The name of the shader uniform as a string. + * @param[in] value The value to set the uniform to.   * - * @param[in] shader The shader to which the uniform belongs - * @param[in] float_name The name of the float uniform - * @param[in] value The value of the float uniform + * @returns Nothing.   */ -void honey_shader_set_float(honey_shader shader, -                            char* float_name, -                            float value); +int honey_shader_set_int(lua_State* L); -/** @brief Set a vec3 uniform. - * @param[in] shader The shader to which the uniform belongs - * @param[in] vector_name The name of the vec3 uniform - * @param[in] value The value of the vector uniform - */ -void honey_shader_set_vec3(honey_shader shader, -                           char* vector_name, -                           vec3 value); - - -/** @brief Set a mat3 uniform. +/** @brief Set a float uniform on a shader. + * + * @param[in] shader The OpenGL shader handle. + * @param[in] name The name of the shader uniform as a string. + * @param[in] value The value to set the uniform to.   * - * @param[in] shader The shader to which the uniform belongs - * @param[in] matrix_name The name of the matrix uniform - * @param[in] value The value of the matrix uniform + * @returns Nothing.   */ -void honey_shader_set_mat3(honey_shader shader, -                           char* matrix_name, -                           mat3 value); +int honey_shader_set_float(lua_State* L); -/** @brief Set a mat4 uniform. +/** @brief Set a vec3 uniform on a shader.   * - * @param[in] shader The shader to which the uniform belongs - * @param[in] matrix_name The name of the matrix uniform - * @param[in] value The value of the matrix uniform + * @param[in] shader The OpenGL shader handle. + * @param[in] name The name of the shader uniform as a string. + * @param[in] value The value to set the uniform to. + * + * @returns Nothing.   */ -void honey_shader_set_mat4(honey_shader shader, -                           char* matrix_name, -                           mat4 value); +int honey_shader_set_vec3(lua_State* L); -/** @brief Set a point_light uniform. +/** @brief Set a vec4 uniform on a shader. + * + * @param[in] shader The OpenGL shader handle. + * @param[in] name The name of the shader uniform as a string. + * @param[in] value The value to set the uniform to.   * - * @param[in] shader The shader to which the uniform belongs - * @param[in] point_light_index The index of the light to set - * @param[in] light The honey_point_light to set + * @returns Nothing.   */ -void honey_shader_set_point_light(honey_shader shader, -                                  int point_light_index, -                                  honey_point_light light); +int honey_shader_set_vec4(lua_State* L); -/** @brief Set a directional_light uniform. +/** @brief Set a mat3 uniform on a shader.   * - * @param[in] shader The shader to which the uniform belongs - * @param[in] directional_light_index The index of the light to set - * @param[in] light The honey_directional_light to set + * @param[in] shader The OpenGL shader handle. + * @param[in] name The name of the shader uniform as a string. + * @param[in] value The value to set the uniform to. + * + * @returns Nothing.   */ -void honey_shader_set_directional_light(honey_shader shader, -                                      int directional_light_index, -                                      honey_directional_light light); +int honey_shader_set_mat3(lua_State* L); -/** @brief Use a shader. +/** @brief Set a mat4 uniform on a shader. + * + * @param[in] shader The OpenGL shader handle. + * @param[in] name The name of the shader uniform as a string. + * @param[in] value The value to set the uniform to. + * + * @returns Nothing.   */ -#define honey_shader_use glUseProgram +int honey_shader_set_mat4(lua_State* L); -/** @brief delete a shader. +/** @brief Delete a shader. + * + * @param[in] shader An OpenGL shader handle. + * + * @returns Nothing.   */ -#define honey_shader_delete glDeleteProgram +int honey_shader_delete(lua_State* L);  #endif | 
