summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authoriurii plugatarov <[email protected]>2024-08-10 14:22:45 +0200
committeriurii plugatarov <[email protected]>2024-08-10 14:22:45 +0200
commit90e85b2fe655a2643535b0f49d99836ac72e724c (patch)
tree66c0656984da7b2b8a6c06c4b0af764919e0e318 /src
parent86eb1bfcf21819492e0ec55cd08127fa8a5c6769 (diff)
downloadogl-90e85b2fe655a2643535b0f49d99836ac72e724c.tar.gz
custom shader loader
Diffstat (limited to '')
-rw-r--r--src/main.c67
-rw-r--r--src/shader.c121
-rw-r--r--src/shader.h19
-rw-r--r--src/shaders/triangle.frag.glsl5
-rw-r--r--src/shaders/triangle.vert.glsl7
5 files changed, 157 insertions, 62 deletions
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 <math.h>
 #include <stdio.h>
 #include <stdlib.h>
+#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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+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 <GL/glew.h>
+
+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;
 }