summaryrefslogtreecommitdiff
path: root/src/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'src/rendering')
-rw-r--r--src/rendering/include/engine/rendering/rendering.h23
-rw-r--r--src/rendering/src/gl.c134
2 files changed, 127 insertions, 30 deletions
diff --git a/src/rendering/include/engine/rendering/rendering.h b/src/rendering/include/engine/rendering/rendering.h
index 7b67248..ed066d6 100644
--- a/src/rendering/include/engine/rendering/rendering.h
+++ b/src/rendering/include/engine/rendering/rendering.h
@@ -28,8 +28,20 @@ typedef struct {
v2_i32 coord;
} Sprite;
+typedef enum {
+ //GL_COMPUTE_SHADER, GL_VERTEX_SHADER, GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER, GL_FRAGMENT_SHADER
+ Shader_Error,
+ Shader_Program, /* Collection of shaders */
+ Shader_Vertex,
+ Shader_Tessellation,
+ Shader_Geometry,
+ Shader_Fragment,
+ Shader_Compute,
+} ShaderType;
+
typedef struct {
/* Shader proram */
+ ShaderType type;
u32 program;
} Shader;
@@ -71,7 +83,7 @@ typedef enum {
RenderDrawCallType_Sprite,
RenderDrawCallType_Model,
} RenderDrawCallType;
-//
+
typedef struct {
RenderDrawCallType type;
union {
@@ -90,6 +102,13 @@ typedef struct {
} data;
} RenderDrawCall;
-RenderObject RenderObject_new(float* model, usize sz, float* uv, usize uv_sz);
+RenderObject RenderObject_new(float* model, Shader* shader, usize sz, float* uv, usize uv_sz);
+
+Shader compile_shader(const char* file_path, const ShaderType shader_type);
+Shader compose_shader(Shader *shaders, usize shaders_len);
+
+u32 ComposeShader(u32 *shaders, usize shaders_len);
+
+ShaderType guess_shadertype_from_filename(const char *restrict fname);
#endif
diff --git a/src/rendering/src/gl.c b/src/rendering/src/gl.c
index bef19b6..ab41f01 100644
--- a/src/rendering/src/gl.c
+++ b/src/rendering/src/gl.c
@@ -1,5 +1,6 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <glad/gl.h>
@@ -11,6 +12,16 @@
extern Platform* GLOBAL_PLATFORM;
+const char* ShaderType_str[] = {
+ [Shader_Error] = "Shader_Error",
+ [Shader_Program] = "Shader_Program",
+ [Shader_Vertex] = "Shader_Vertex",
+ [Shader_Tessellation] = "Shader_Tessellation",
+ [Shader_Geometry] = "Shader_Geometry",
+ [Shader_Fragment] = "Shader_Fragment",
+ [Shader_Compute] = "Shader_Compute",
+};
+
isize f_get_sz(FILE* f) {
if (f == NULL) {
ERROR("File was null!");
@@ -28,22 +39,37 @@ isize f_get_sz(FILE* f) {
return size;
}
-const GLuint
-compile_shader(const GladGLContext *gl, const char* file_path, const GLenum shader_type) {
+Shader compile_shader(const char* file_path, const ShaderType shader_type) {
GLuint shaderID = 0;
+ GLenum shadertype = GL_INVALID_ENUM;
+
+ GLint Result = GL_FALSE;
+ int InfoLogLength;
+
+ char* source = NULL;
+ FILE* file = NULL;
+
+ const GladGLContext* gl = GLOBAL_PLATFORM->window->context;
if (file_path == NULL) {
WARN("Empty path to shader");
- return (GLuint)0;
+ return (Shader){.program = 0, .type = Shader_Error};
}
- GLint Result = GL_FALSE;
- int InfoLogLength;
+ switch (shader_type) {
+ case Shader_Vertex:
+ shadertype = GL_VERTEX_SHADER;
+ break;
+ case Shader_Fragment:
+ shadertype = GL_FRAGMENT_SHADER;
+ break;
+ default: break;
+ }
- char* source;
- FILE* file = fopen(file_path, "r");
+ file = fopen(file_path, "r");
- shaderID = gl->CreateShader(shader_type);
+ shaderID = gl->CreateShader(shadertype);
+ LOG("CREATED SHADER ID %d", shaderID);
if(file != NULL) {
const i64 size = f_get_sz(file);
@@ -56,12 +82,12 @@ compile_shader(const GladGLContext *gl, const char* file_path, const GLenum shad
fclose(file);
} else {
ERROR("Cannot open \"" TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET"\".", file_path);
- return 0;
+ return (Shader){.program = 0, .type = Shader_Error};
}
// Compile shader
INFO("Compiling shader \"" TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET"\".", file_path);
- char const * src_ptr = source;
+ char const* src_ptr = source;
gl->ShaderSource(shaderID, 1, &src_ptr , NULL);
gl->CompileShader(shaderID);
@@ -74,31 +100,31 @@ compile_shader(const GladGLContext *gl, const char* file_path, const GLenum shad
ERROR("Failed to compile shader: " TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET, msg);
free(msg);
}
- free(source);
+ //free(source);
- return shaderID;
+ return (Shader){.program = shaderID, .type = shader_type};
}
// http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/
-GLuint LoadShaders(
+GLuint load_shaders(
const GladGLContext* gl,
- const char * vertex_file_path,
- const char * fragment_file_path) {
+ const char* vertex_file_path,
+ const char* fragment_file_path) {
GLint Result = GL_FALSE;
int InfoLogLength;
// Create the shaders
- const GLuint vertexShader = compile_shader(gl, vertex_file_path, GL_VERTEX_SHADER);
- const GLuint fragmentShader = compile_shader(gl, fragment_file_path, GL_FRAGMENT_SHADER);
+ const Shader vertexShader = compile_shader(vertex_file_path, Shader_Vertex);
+ const Shader fragmentShader = compile_shader(fragment_file_path, Shader_Fragment);
// Link the program
INFO("Linking program");
GLuint ProgramID = gl->CreateProgram();
- if (vertex_file_path != NULL) gl->AttachShader(ProgramID, vertexShader);
- if (fragment_file_path != NULL) gl->AttachShader(ProgramID, fragmentShader);
+ if (vertex_file_path != NULL) gl->AttachShader(ProgramID, vertexShader.program);
+ if (fragment_file_path != NULL) gl->AttachShader(ProgramID, fragmentShader.program);
gl->LinkProgram(ProgramID);
@@ -112,24 +138,64 @@ GLuint LoadShaders(
free(msg);
}
- gl->DetachShader(ProgramID, vertexShader);
- gl->DetachShader(ProgramID, fragmentShader);
+ gl->DetachShader(ProgramID, vertexShader.program);
+ gl->DetachShader(ProgramID, fragmentShader.program);
- gl->DeleteShader(vertexShader);
- gl->DeleteShader(fragmentShader);
+ gl->DeleteShader(vertexShader.program);
+ gl->DeleteShader(fragmentShader.program);
return ProgramID;
}
-RenderObject RenderObject_new(float* model, usize sz, float* uv, usize uv_sz) {
+/* Returns a shader program */
+Shader compose_shader(Shader *shaders, usize shaders_len) {
+ const GladGLContext* gl = GLOBAL_PLATFORM->window->context;
+ GLint Result = GL_FALSE;
+ int InfoLogLength = 0;
+
+ if (shaders_len == 0) {
+ ERROR("No shaders provided!");
+ return (Shader){.program = 0, .type = Shader_Error};
+ }
+
+ u32 prog = gl->CreateProgram();
+
+ for (int i = 0; i < shaders_len; i++) {
+ DEBUG("Attaching shader [%d] : %s (%d) = %d\n", i, ShaderType_str[shaders[i].type], shaders[i].type, shaders[i].program);
+ gl->AttachShader(prog, shaders[i].program);
+ }
+
+ gl->LinkProgram(prog);
+
+ // Check the program
+ gl->GetProgramiv(prog, GL_LINK_STATUS, &Result);
+ gl->GetProgramiv(prog, GL_INFO_LOG_LENGTH, &InfoLogLength);
+ if ( InfoLogLength > 0 ) {
+ char* msg = calloc(InfoLogLength + 1, sizeof(char));
+ gl->GetShaderInfoLog(prog, InfoLogLength, NULL, msg);
+ ERROR("(Compose) Compiling shader[%d]: " TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET, InfoLogLength, msg);
+ free(msg);
+ }
+
+ for (int i = 0; i < shaders_len; i++) {
+ gl->DetachShader(prog, shaders[i].program);
+ }
+
+ return (Shader){.program = prog, .type = Shader_Program};
+}
+
+RenderObject RenderObject_new(float* model, Shader* shader, usize sz, float* uv, usize uv_sz) {
GladGLContext *gl = GLOBAL_PLATFORM->window->context;
RenderObject o;
+ //DEBUG("RenderObject got %d: %s\n", shader->program, ShaderType_str[shader->type]);
+
// TODO: implement index buffer!
gl->GenVertexArrays(1, &(o.vao));
gl->BindVertexArray(o.vao);
+ /* For each buffer in the shader, */
gl->GenBuffers(1, &(o.vbo));
gl->BindBuffer(GL_ARRAY_BUFFER, o.vbo);
gl->BufferData(GL_ARRAY_BUFFER, sz, model, GL_STATIC_DRAW);
@@ -137,11 +203,23 @@ RenderObject RenderObject_new(float* model, usize sz, float* uv, usize uv_sz) {
gl->GenBuffers(1, &(o.col));
gl->BindBuffer(GL_ARRAY_BUFFER, o.col);
gl->BufferData(GL_ARRAY_BUFFER, uv_sz, uv, GL_STATIC_DRAW);
- //gl->GenBuffers(1, &(o.ibo));
- //gl->BindBuffer(GL_ARRAY_BUFFER, o.ibo);
- //gl->BufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);
- o.shader.program = LoadShaders(gl, "shader.vert", "shader.frag");
+ o.shader = *shader;
return o;
}
+
+ShaderType guess_shadertype_from_filename(const char *restrict fname) {
+ u32 stype = 0;
+ const usize path_len = strlen(fname);
+
+ if (path_len <= 4) {
+ ERROR("Unable to determine shader type from suffix! (%s)", fname);
+ return Shader_Error;
+ }
+
+ if (!strncmp(".vert", &fname[path_len - 5], 5)) { return Shader_Vertex; }
+ if (!strncmp(".frag", &fname[path_len - 5], 5)) { return Shader_Fragment; }
+
+ return Shader_Error;
+}