aboutsummaryrefslogtreecommitdiff
path: root/src/shader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader.c')
-rw-r--r--src/shader.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/shader.c b/src/shader.c
new file mode 100644
index 0000000..e21277f
--- /dev/null
+++ b/src/shader.c
@@ -0,0 +1,102 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <GL/glew.h>
+#include "shader.h"
+
+static char *getShaderSource(const char *shaderPath);
+static void checkShaderCompile(unsigned int shader, const char *shaderPath);
+static void checkProgramLink(unsigned int shader);
+
+char
+*getShaderSource(const char *shaderPath)
+{
+ long fileSize;
+ char *shaderSource;
+ FILE *shaderFile = fopen(shaderPath, "r");
+
+ if (!shaderFile) {
+ perror("getShaderSource() ERROR");
+ exit(1);
+ }
+
+ fseek(shaderFile, 0L, SEEK_END);
+ fileSize = ftell(shaderFile);
+ if (!fileSize) {
+ fprintf(stderr, "getShaderSource() ERROR: %s file is empty\n", shaderPath);
+ exit(1);
+ }
+
+ rewind(shaderFile);
+
+ shaderSource = malloc(fileSize * sizeof(char));
+ if (!fscanf(shaderFile, "%[^\\]", shaderSource)) {
+ perror("getShaderSource() ERROR");
+ exit(1);
+ }
+
+ fclose(shaderFile);
+ return shaderSource;
+}
+
+void
+checkShaderCompile(unsigned int shader, const char *shaderPath)
+{
+ int success;
+ char infoLog[512];
+
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
+ if (!success) {
+ glGetShaderInfoLog(shader, 512, NULL, infoLog);
+ fprintf(stderr, "shaderCompile() ERROR\n%s %s\n", shaderPath, infoLog);
+ exit(1);
+ }
+}
+
+void
+checkProgramLink(unsigned int shaderProgram)
+{
+ int success;
+ char infoLog[512];
+ glLinkProgram(shaderProgram);
+ glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
+ if (!success) {
+ glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
+ fprintf(stderr, "shaderProgramLink() ERROR\n%s\n", infoLog);
+ exit(1);
+ }
+}
+
+unsigned int
+shaderCreateProgram(const char *vertexShaderPath, const char *fragmentShaderPath)
+{
+ unsigned int vertexShader, fragmentShader, shaderProgram;
+ char *vertexShaderSource, *fragmentShaderSource;
+
+ vertexShader = glCreateShader(GL_VERTEX_SHADER);
+ fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+
+ vertexShaderSource = getShaderSource(vertexShaderPath);
+ fragmentShaderSource = getShaderSource(fragmentShaderPath);
+
+ glShaderSource(vertexShader, 1, (const char **)&vertexShaderSource, NULL);
+ glCompileShader(vertexShader);
+ checkShaderCompile(vertexShader, vertexShaderPath);
+
+ glShaderSource(fragmentShader, 1, (const char **)&fragmentShaderSource, NULL);
+ glCompileShader(fragmentShader);
+ checkShaderCompile(fragmentShader, fragmentShaderPath);
+
+ shaderProgram = glCreateProgram();
+ glAttachShader(shaderProgram, vertexShader);
+ glAttachShader(shaderProgram, fragmentShader);
+ glLinkProgram(shaderProgram);
+ checkProgramLink(shaderProgram);
+
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+ free(vertexShaderSource);
+ free(fragmentShaderSource);
+
+ return shaderProgram;
+}
Feel free to download, copy and edit any repo