tinyrenderer/src/shader/shader.c

59 lines
1.8 KiB
C

#include "shader.h"
#include "aliases.h"
#define MAX_SHADER_COUNT 2048
typedef struct shader_repo ShaderRepo;
struct shader_repo {
void *shaders[MAX_SHADER_COUNT];
VertexShader *vertex_funcs[MAX_SHADER_COUNT];
FragmentShader *fragment_funcs[MAX_SHADER_COUNT];
u64 count;
};
internal ShaderRepo g_repository = {0};
ShaderID register_shader(void *shader, VertexShader *vertex, FragmentShader *fragment) {
if (g_repository.count + 1 >= MAX_SHADER_COUNT) {
return INVALID_SHADER;
}
++(g_repository.count);
g_repository.shaders[g_repository.count] = shader;
g_repository.vertex_funcs[g_repository.count] = vertex;
g_repository.fragment_funcs[g_repository.count] = fragment;
return (ShaderID){g_repository.count};
}
VertexData run_vertex_shader(ShaderID shader, const VertexData *vert, u8 index, const Model *model) {
if (IS_INVALID_SHADER(shader) || shader.id > g_repository.count || !vert || !model) {
return (VertexData){0};
}
void *shader_obj = g_repository.shaders[shader.id];
VertexShader *vertex_func = g_repository.vertex_funcs[shader.id];
if (!shader_obj || !vertex_func) {
return (VertexData){0};
}
return vertex_func(shader_obj, vert, index, model);
}
FragmentResult run_fragment_shader(ShaderID shader, const V3f *barycentric, const V4f *colour,
const Model *model) {
if (IS_INVALID_SHADER(shader) || shader.id > g_repository.count || !colour) {
return DISCARDED_FRAGMENT;
}
void *shader_obj = g_repository.shaders[shader.id];
FragmentShader *fragment_func = g_repository.fragment_funcs[shader.id];
if (!shader_obj || !fragment_func) {
return DISCARDED_FRAGMENT;
}
return fragment_func(shader_obj, barycentric, colour, model);
}