From 7294628c2098416ffb4f8562686e6863bec6526b Mon Sep 17 00:00:00 2001
From: matthew <matthew@owens.tech>
Date: Sat, 18 Aug 2018 22:02:08 +0100
Subject: [PATCH] moved shader handling to shader.h, removed tri2 shader,
 altered tri shader to accept vertex colors

---
 gl/main.c                 | 109 ++++++++++---------------------
 gl/shader.c               | 133 ++++++++++++++++++++++++++++++++++++++
 gl/shader.h               |  23 +++++++
 gl/shaderLoader.c         |  75 ---------------------
 gl/shaderLoader.h         |  18 ------
 gl/shaders/tri/tri.frag   |   3 +-
 gl/shaders/tri/tri.vert   |   6 +-
 gl/shaders/tri2/tri2.frag |   7 --
 gl/shaders/tri2/tri2.vert |   7 --
 9 files changed, 196 insertions(+), 185 deletions(-)
 create mode 100644 gl/shader.c
 create mode 100644 gl/shader.h
 delete mode 100644 gl/shaderLoader.c
 delete mode 100644 gl/shaderLoader.h
 delete mode 100644 gl/shaders/tri2/tri2.frag
 delete mode 100644 gl/shaders/tri2/tri2.vert

diff --git a/gl/main.c b/gl/main.c
index ef5381b..ea5e7dd 100644
--- a/gl/main.c
+++ b/gl/main.c
@@ -2,26 +2,23 @@
 #include <stdbool.h>
 #include <SDL2/SDL.h>
 #include <GL/glew.h>
-#include "shaderLoader.h"
+#include <math.h>
+#include "shader.h"
 #include "err.h"
 
 static SDL_Window *window = NULL;
 static SDL_GLContext *context = NULL;
 static int screen_width = 1280;
 static int screen_height = 720;
+static bool quit = false;
+static Uint32 itime;
 
 static float vertices[] = {
-	0.0f, 0.5f, 0.0f,		// top right
-	0.0f, -0.5f, 0.0f,		// bottom right
-	-1.0f, -0.5f, 0.0f,		// bottom left
-	-1.0f, 0.5f, 0.0f		// top left
-};
-
-static float vertices2[] = {
-	1.0f, 0.5f, 0.0f,		// top right
-	1.0f, -0.5f, 0.0f,		// bottom right
-	0.0f, -0.5f, 0.0f,		// bottom left
-	0.0f, 0.5f, 0.0f		// top left
+	// positions		// colors
+	0.5f, 0.5f, 0.0f,	1.0f, 0.0f, 0.5f,	// top right
+	0.5f, -0.5f, 0.0f,	0.0f, 1.0f, 0.0f,	// bottom right
+	-0.5f, -0.5f, 0.0f,	0.5f, 0.0f, 0.5f,	// bottom left
+	-0.5f, 0.5f, 0.0f,	0.5f, 0.0f, 1.0f	// top left
 };
 
 static unsigned int indices[] = {
@@ -30,60 +27,28 @@ static unsigned int indices[] = {
 };
 
 static unsigned int ebo;
-static unsigned int vbos[2], vaos[2];
-static unsigned int vertShader[2], fragShader[2], shaderProgram[2];
-static GLchar *vertSrc[2];
-static GLchar *fragSrc[2];
+static unsigned int vbo, vao;
+Shader *shader = NULL;
 
 static void initShapes()
 {
-	glGenBuffers(2, vbos);
-	glGenVertexArrays(2, vaos);
+	glGenBuffers(1, &vbo);
+	glGenVertexArrays(1, &vao);
 	glGenBuffers(1, &ebo);
 
 	// first shape
-	glBindVertexArray(vaos[0]);
-	glBindBuffer(GL_ARRAY_BUFFER, vbos[0]);
+	glBindVertexArray(vao);
+	glBindBuffer(GL_ARRAY_BUFFER, vbo);
 	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
+	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)0);
 	glEnableVertexAttribArray(0); // param is the location of the attrib to enable.
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
-	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
-
-
-	// second shape
-	glBindVertexArray(vaos[1]);
-	glBindBuffer(GL_ARRAY_BUFFER, vbos[1]);
-	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
-	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
-	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)(3*sizeof(float)));
+	glEnableVertexAttribArray(1);
 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
 	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
 
 	glBindVertexArray(0);	// unbinding vao, since we're done
-
-	vertSrc[0] = shader_load_src("tri", VERTEX);
-	vertSrc[1] = shader_load_src("tri2", VERTEX);
-	fragSrc[0] = shader_load_src("tri", FRAGMENT);
-	fragSrc[1] = shader_load_src("tri2", FRAGMENT);
-
-	for(int i = 0; i < 2; ++i){
-		vertShader[i] = glCreateShader(GL_VERTEX_SHADER);
-		shader_compile(vertShader[i], vertSrc[i], "vertex");
-		fragShader[i] = glCreateShader(GL_FRAGMENT_SHADER);
-		shader_compile(fragShader[i], fragSrc[i], "Fragment");
-
-		shaderProgram[i] = glCreateProgram();
-		glAttachShader(shaderProgram[i], vertShader[i]);
-		glAttachShader(shaderProgram[i], fragShader[i]);
-		glLinkProgram(shaderProgram[i]);
-
-		// cleaning up
-		glDeleteShader(vertShader[i]);
-		glDeleteShader(fragShader[i]);
-		shader_free_src(vertSrc[i]);
-		shader_free_src(fragSrc[i]);
-	}
+	shader = crpgShaderNew("tri");
 }
 
 static bool init()
@@ -125,45 +90,37 @@ static bool init()
 	return true;
 }
 
+static void update()
+{
+	SDL_Event e;
+	while(SDL_PollEvent(&e) != 0){
+		if(e.type == SDL_QUIT){
+			quit = true;
+		}
+	}
+}
+
 static void render()
 {
 	glClearColor(0.2, 0.3, 0.3, 1.0);
 	glClear(GL_COLOR_BUFFER_BIT);
-	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
-	glUseProgram(shaderProgram[0]);
-	glBindVertexArray(vaos[0]);
-	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
-
-	glUseProgram(shaderProgram[1]);
-	glBindVertexArray(vaos[1]);
+	crpgShaderUse(shader);
+	glBindVertexArray(vao);
 	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
 	SDL_GL_SwapWindow(window);
 }
 
 int main()
 {
-	Uint32 itime;
-	Uint32 ctime = 0;
-	SDL_Event e;
-
 	if(!init())
 		return -1;
 
 	initShapes();
 	itime = SDL_GetTicks();
 
-
-	while(ctime != itime + 10000){
-		ctime = SDL_GetTicks();
-
-		while(SDL_PollEvent(&e) != 0){
-			if (e.type == SDL_QUIT){
-				printf("quitting!\n");
-				ctime = itime + 10000;
-			}
-		}
-
+	while(!quit){
+		update();
 		render();
 	}
 
diff --git a/gl/shader.c b/gl/shader.c
new file mode 100644
index 0000000..e7c4553
--- /dev/null
+++ b/gl/shader.c
@@ -0,0 +1,133 @@
+#include "shader.h"
+#include <GL/glew.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "fileRead.h"
+#include "err.h"
+typedef struct {
+	int id;
+} Shader_t;
+
+static char *fileEnds[] = {
+	".vert",
+	".frag",
+	".comp",
+	".tesc",
+	".tese"
+};
+
+static char *dirPath = "gl/shaders/";
+
+char *shaderLoadSrc(const char *name, enum ShaderType type)
+{
+	GLchar *src = NULL;
+
+	int nSize = strlen(name);
+	int eSize = strlen(fileEnds[type]);
+	int dSize = strlen(dirPath);
+
+	int tSize = dSize + (2*nSize) + eSize + 2;
+
+	// constructing the final path string
+	char *path = malloc(tSize);
+
+	strcpy(path, dirPath);
+	strcat(path, name);
+	strcat(path, "/");
+	strcat(path, name);
+	strcat(path, fileEnds[type]);
+
+	src = readFile(path);
+	free(path);
+	return src;
+}
+
+int shaderCompile(unsigned int shader, const GLchar *shaderSrc, const char *description)
+{
+	int success = GL_FALSE;
+	char log[512];
+	char out[512];
+
+	strcpy(out, "failed to compile shader: ");
+	strcat(out, description);
+
+	if(shaderSrc){
+		glShaderSource(shader, 1, &shaderSrc, NULL);
+		glCompileShader(shader);
+		glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
+
+		if(!success){
+			glGetShaderInfoLog(shader, 512, NULL, log);
+			strcat(out, "!\n");
+			strcat(out, log);
+			err_output(out);
+		}
+	} else {
+		strcat(out, " source is NULL!\n");
+		err_output(out);
+	}
+
+	return success;
+}
+
+int getGlMacro(enum ShaderType st){
+	switch(st){
+		case CRPG_SHADER_VERTEX:
+			return GL_VERTEX_SHADER;
+		case CRPG_SHADER_FRAGMENT:
+			return GL_FRAGMENT_SHADER;
+		case CRPG_SHADER_GEOMETRY:
+			return GL_GEOMETRY_SHADER;
+		case CRPG_SHADER_COMPUTE:
+			return GL_COMPUTE_SHADER;
+		case CRPG_SHADER_TESSCONTROL:
+			return GL_TESS_CONTROL_SHADER;
+		case CRPG_SHADER_TESSEVAL:
+			return GL_TESS_EVALUATION_SHADER;
+	}
+
+	return 0;
+}
+
+Shader *crpgShaderNew(const char *shaderName){
+	Shader_t *s = malloc(sizeof(Shader_t));
+	GLchar *src;
+	unsigned int shader;
+	char desc[128];
+
+	s->id = glCreateProgram();
+
+	for(int i = 0; i < CRPG_SHADER_LAST; ++i){
+		src = shaderLoadSrc(shaderName, i);
+		if(src){
+			shader = glCreateShader(getGlMacro(i));
+			// constructing a descriptive string for the compiling source
+			strcpy(desc, shaderName);
+			strcat(desc, fileEnds[i]);
+
+			if(shaderCompile(shader, src, desc)){
+				glAttachShader(s->id, shader);
+
+				// Shader has been attached, so we can delete it
+				glDeleteShader(shader);
+				free(src);
+			}
+		}
+	}
+
+	glLinkProgram(s->id);
+	return (Shader *)s;
+}
+
+void crpgShaderFree(Shader *s)
+{
+	Shader_t *st = (Shader_t *)s;
+	glDeleteProgram(st->id);
+}
+
+void crpgShaderUse(Shader *s)
+{
+	Shader_t *st = (Shader_t *)s;
+	glUseProgram(st->id);
+}
diff --git a/gl/shader.h b/gl/shader.h
new file mode 100644
index 0000000..7dad063
--- /dev/null
+++ b/gl/shader.h
@@ -0,0 +1,23 @@
+#ifndef SHADER_H
+#define SHADER_H
+#include <stdbool.h>
+enum ShaderType
+{
+	CRPG_SHADER_VERTEX = 0,
+	CRPG_SHADER_FRAGMENT,
+	CRPG_SHADER_GEOMETRY,
+	CRPG_SHADER_COMPUTE,
+	CRPG_SHADER_TESSCONTROL,
+	CRPG_SHADER_TESSEVAL,
+	CRPG_SHADER_LAST
+};
+
+typedef struct {} Shader;
+
+Shader *crpgShaderNew(const char *shaderName);
+void crpgShaderUse(Shader *s);
+void crpgShaderSetBool(Shader *s, const char *name, bool val);
+void crpgShaderSetInt(Shader *s, const char *name, int val);
+void crpgShaderSetFloat(Shader *s, const char *name, float val);
+void crpgShaderFree(Shader *s);
+#endif//SHADER_H
diff --git a/gl/shaderLoader.c b/gl/shaderLoader.c
deleted file mode 100644
index 9bccfaf..0000000
--- a/gl/shaderLoader.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include "shaderLoader.h"
-#include "fileRead.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "err.h"
-
-static char *fileEnds[] = {
-	".vert",
-	".frag",
-	".comp",
-	".tesc",
-	".tese"
-};
-static char *dirPath = "gl/shaders/";
-
-char *shader_load_src(const char *name, enum ShaderType type)
-{
-	GLchar *src = NULL;
-
-	int nSize = strlen(name);
-	int eSize = strlen(fileEnds[type]);
-	int dSize = strlen(dirPath);
-
-	int tSize = dSize + (2*nSize) + eSize + 2;
-
-	// constructing the final path string
-	char *path = malloc(tSize);
-	printf("sizes: dSize=%d nSize=%d, eSize=%d\n", dSize, nSize, eSize);
-	printf("total allocated %d\n", tSize);
-
-	strcpy(path, dirPath);
-	strcat(path, name);
-	strcat(path, "/");
-	strcat(path, name);
-	strcat(path, fileEnds[type]);
-
-	// debug output
-	printf("path length is %ld\n", strlen(path));
-	printf("loading shader from file '%s'\n\n", path);
-	src = readFile(path);
-	free(path);
-	return src;
-}
-
-void shader_compile(unsigned int shader, const GLchar *shaderSrc, const char *description)
-{
-	int success;
-	char log[512];
-	char out[512];
-
-	strcpy(out, "failed to compile shader: ");
-	strcat(out, description);
-
-	if(shaderSrc){
-		glShaderSource(shader, 1, &shaderSrc, NULL);
-		glCompileShader(shader);
-		glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
-
-		if(!success){
-			glGetShaderInfoLog(shader, 512, NULL, log);
-			strcat(out, "!\n");
-			strcat(out, log);
-			err_output(out);
-		}
-	} else {
-		strcat(out, " source is NULL!\n");
-		err_output(out);
-	}
-}
-
-void shader_free_src(GLchar *src)
-{
-	free(src);
-}
diff --git a/gl/shaderLoader.h b/gl/shaderLoader.h
deleted file mode 100644
index 572f5d6..0000000
--- a/gl/shaderLoader.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef SHADER_LOADER
-#define SHADER_LOADER
-#include <GL/glew.h>
-
-enum ShaderType
-{
-	VERTEX = 0,
-	FRAGMENT,
-	GEOMETRY,
-	COMPUTE,
-	TESSCONTROL,
-	TESSEVAL
-};
-
-char *shader_load_src(const char *name, enum ShaderType type);
-void shader_compile(unsigned int shader, const GLchar *shaderSrc, const char *description);
-void shader_free_src(GLchar *src);
-#endif//SHADER_LOADER
diff --git a/gl/shaders/tri/tri.frag b/gl/shaders/tri/tri.frag
index b162430..567411c 100644
--- a/gl/shaders/tri/tri.frag
+++ b/gl/shaders/tri/tri.frag
@@ -1,7 +1,8 @@
 #version 330 core
 out vec4 fragColor;
+in vec3 vCol;
 
 void main()
 {
-	fragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
+	fragColor = vec4(vCol, 1.0);
 }
diff --git a/gl/shaders/tri/tri.vert b/gl/shaders/tri/tri.vert
index 0e6b9fc..f90acd7 100644
--- a/gl/shaders/tri/tri.vert
+++ b/gl/shaders/tri/tri.vert
@@ -1,7 +1,11 @@
 #version 330 core
 layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec3 aCol;
+
+out vec3 vCol;
 
 void main()
 {
-	gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
+	gl_Position = vec4(aPos, 1.0);
+	vCol = aCol;
 }
diff --git a/gl/shaders/tri2/tri2.frag b/gl/shaders/tri2/tri2.frag
deleted file mode 100644
index 7eb0d06..0000000
--- a/gl/shaders/tri2/tri2.frag
+++ /dev/null
@@ -1,7 +0,0 @@
-#version 330 core
-out vec4 fragColor;
-
-void main()
-{
-	fragColor = vec4(0.2f, 0.5f, 1.0f, 1.0f);
-}
diff --git a/gl/shaders/tri2/tri2.vert b/gl/shaders/tri2/tri2.vert
deleted file mode 100644
index 0e6b9fc..0000000
--- a/gl/shaders/tri2/tri2.vert
+++ /dev/null
@@ -1,7 +0,0 @@
-#version 330 core
-layout (location = 0) in vec3 aPos;
-
-void main()
-{
-	gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
-}
-- 
2.20.1