From 90e85b2fe655a2643535b0f49d99836ac72e724c Mon Sep 17 00:00:00 2001 From: iurii plugatarov Date: Sat, 10 Aug 2024 15:22:45 +0300 Subject: custom shader loader --- src/main.c | 67 +++-------------------- src/shader.c | 121 +++++++++++++++++++++++++++++++++++++++++ src/shader.h | 19 +++++++ src/shaders/triangle.frag.glsl | 5 +- src/shaders/triangle.vert.glsl | 7 ++- 5 files changed, 157 insertions(+), 62 deletions(-) create mode 100644 src/shader.c create mode 100644 src/shader.h diff --git a/src/main.c b/src/main.c index a125823..96882b6 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include #include #include +#include "shader.h" void on_resize(GLFWwindow *win, int width, int height) { glViewport(0, 0, width, height); @@ -53,65 +54,15 @@ int main() { unsigned int VBO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * 6, vertices, - GL_STATIC_DRAW); - - const char *vertex_shader_src = - "#version 330 core\n" - "layout (location = 0) in vec3 aPos;\n" - "layout (location = 1) in vec3 aColor;\n" - "out vec3 ourColor;\n" - "void main()\n" - "{\n" - " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" - " ourColor = aColor;\n" - "}\0"; - - unsigned int vertex_shader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertex_shader, 1, &vertex_shader_src, NULL); - glCompileShader(vertex_shader); - - int success; - char info_log[512]; - glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); - - if (!success) { - glGetShaderInfoLog(vertex_shader, 512, NULL, info_log); - printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n%s\n", info_log); - } - - const char *fragment_shader_src = "#version 330 core\n" - "out vec4 FragColor;\n" - "in vec3 ourColor;\n" - "void main()\n" - "{\n" - " FragColor = vec4(ourColor, 1.0);\n" - "}\0"; - - unsigned int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment_shader, 1, &fragment_shader_src, NULL); - glCompileShader(fragment_shader); - glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success); - - if (!success) { - glGetShaderInfoLog(fragment_shader, 512, NULL, info_log); - printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n%s\n", info_log); - } - - unsigned int shader_program = glCreateProgram(); - glAttachShader(shader_program, vertex_shader); - glAttachShader(shader_program, fragment_shader); - glLinkProgram(shader_program); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - glGetProgramiv(shader_program, GL_LINK_STATUS, &success); - if (!success) { - glGetProgramInfoLog(shader_program, 512, NULL, info_log); - printf("ERROR::SHADER::PROGRAM::LINK_FAILED\n%s\n", info_log); + // Create and compile shaders using our new shader implementation + Shader* shader = shader_create("src/shaders/triangle.vert.glsl", "src/shaders/triangle.frag.glsl"); + if (!shader) { + glfwTerminate(); + return -1; } - glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); - unsigned int VAO; glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); @@ -123,7 +74,7 @@ int main() { (void *)(3 * sizeof(float))); glEnableVertexAttribArray(1); - glUseProgram(shader_program); + shader_use(shader); while (!glfwWindowShouldClose(window)) { glClearColor(0.1f, 0.1f, 0.25f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); @@ -137,7 +88,7 @@ int main() { glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); - glDeleteProgram(shader_program); + shader_delete(shader); glfwTerminate(); return 0; diff --git a/src/shader.c b/src/shader.c new file mode 100644 index 0000000..7e1b58f --- /dev/null +++ b/src/shader.c @@ -0,0 +1,121 @@ +#include "shader.h" +#include +#include +#include + +static char *read_file(const char *file_path) { + FILE *file = fopen(file_path, "r"); + if (!file) { + printf("Failed to open file: %s\n", file_path); + return NULL; + } + + fseek(file, 0, SEEK_END); + long file_size = ftell(file); + fseek(file, 0, SEEK_SET); + + char *buffer = (char *)malloc(file_size + 1); + if (!buffer) { + printf("Failed to allocate memory for file: %s\n", file_path); + fclose(file); + return NULL; + } + + fread(buffer, 1, file_size, file); + buffer[file_size] = '\0'; + + fclose(file); + return buffer; +} + +static unsigned int compile_shader(const char *source, GLenum shader_type) { + unsigned int shader = glCreateShader(shader_type); + glShaderSource(shader, 1, &source, NULL); + glCompileShader(shader); + + int success; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { + char info_log[512]; + glGetShaderInfoLog(shader, 512, NULL, info_log); + printf("Shader compilation failed: %s\n", info_log); + return 0; + } + + return shader; +} + +Shader *shader_create(const char *vertex_path, const char *fragment_path) { + Shader *shader = (Shader *)malloc(sizeof(Shader)); + if (!shader) { + printf("Failed to allocate memory for shader\n"); + return NULL; + } + + char *vertex_source = read_file(vertex_path); + char *fragment_source = read_file(fragment_path); + + if (!vertex_source || !fragment_source) { + free(shader); + free(vertex_source); + free(fragment_source); + return NULL; + } + + unsigned int vertex_shader = compile_shader(vertex_source, GL_VERTEX_SHADER); + unsigned int fragment_shader = + compile_shader(fragment_source, GL_FRAGMENT_SHADER); + + free(vertex_source); + free(fragment_source); + + if (!vertex_shader || !fragment_shader) { + free(shader); + return NULL; + } + + shader->program = glCreateProgram(); + glAttachShader(shader->program, vertex_shader); + glAttachShader(shader->program, fragment_shader); + glLinkProgram(shader->program); + + int success; + glGetProgramiv(shader->program, GL_LINK_STATUS, &success); + if (!success) { + char info_log[512]; + glGetProgramInfoLog(shader->program, 512, NULL, info_log); + printf("Shader program linking failed: %s\n", info_log); + free(shader); + return NULL; + } + + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + + return shader; +} + +void shader_use(Shader *shader) { glUseProgram(shader->program); } + +void shader_delete(Shader *shader) { + glDeleteProgram(shader->program); + free(shader); +} + +void shader_set_int(Shader *shader, const char *name, int value) { + glUniform1i(glGetUniformLocation(shader->program, name), value); +} + +void shader_set_float(Shader *shader, const char *name, float value) { + glUniform1f(glGetUniformLocation(shader->program, name), value); +} + +void shader_set_vec3(Shader *shader, const char *name, float x, float y, + float z) { + glUniform3f(glGetUniformLocation(shader->program, name), x, y, z); +} + +void shader_set_mat4(Shader *shader, const char *name, const float *value) { + glUniformMatrix4fv(glGetUniformLocation(shader->program, name), 1, GL_FALSE, + value); +} diff --git a/src/shader.h b/src/shader.h new file mode 100644 index 0000000..ee06930 --- /dev/null +++ b/src/shader.h @@ -0,0 +1,19 @@ +#ifndef SHADER_H +#define SHADER_H + +#include + +typedef struct { + GLuint program; +} Shader; + +Shader *shader_create(const char *vertex_path, const char *fragment_path); +void shader_use(Shader *shader); +void shader_delete(Shader *shader); +void shader_set_int(Shader *shader, const char *name, int value); +void shader_set_float(Shader *shader, const char *name, float value); +void shader_set_vec3(Shader *shader, const char *name, float x, float y, + float z); +void shader_set_mat4(Shader *shader, const char *name, const float *value); + +#endif diff --git a/src/shaders/triangle.frag.glsl b/src/shaders/triangle.frag.glsl index 664c399..b3dcd05 100644 --- a/src/shaders/triangle.frag.glsl +++ b/src/shaders/triangle.frag.glsl @@ -1,6 +1,7 @@ #version 330 core out vec4 FragColor; +in vec3 ourColor; void main() { - FragColor = vec4(1.0, 0.0, 0.0, 1.0); -} + FragColor = vec4(ourColor, 1.0); +} diff --git a/src/shaders/triangle.vert.glsl b/src/shaders/triangle.vert.glsl index dbef13e..f1dbe00 100644 --- a/src/shaders/triangle.vert.glsl +++ b/src/shaders/triangle.vert.glsl @@ -1,6 +1,9 @@ #version 330 core -layout (location = 0) in vec2 aPos; +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aColor; +out vec3 ourColor; void main() { - gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); + gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); + ourColor = aColor; } -- cgit 1.4.1-2-gfad0