diff options
| author | Uneven Prankster <unevenprankster@protonmail.com> | 2023-07-12 13:22:29 -0300 |
|---|---|---|
| committer | Uneven Prankster <unevenprankster@protonmail.com> | 2023-07-12 13:22:29 -0300 |
| commit | fa2bdd711212ba6b7a94a20971e8bfa281e73296 (patch) | |
| tree | 6713b3c0379507d49558287b71dd360ce188a2f0 /src/shader_sys.c | |
lol
Diffstat (limited to 'src/shader_sys.c')
| -rw-r--r-- | src/shader_sys.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/shader_sys.c b/src/shader_sys.c new file mode 100644 index 0000000..cd8de3e --- /dev/null +++ b/src/shader_sys.c @@ -0,0 +1,139 @@ +#include "utils.h" + +#include <stdlib.h> + +#define MAX_SHADER_SIZE 8 + +// TODO: Compute? +// Would probably require a different path altogther +// due to how those shaders are compiled tho +typedef enum{ + VERTEX = 0, + FRAGMENT = 1 +}ShaderStep; + +// This returns *allocated* memory, +// should be manually free()'ed or some kind of arena used. +static char* shader_block_preprocess(const char* shader_source, ShaderStep shader_step) { + static const char* start_markers[2] = {"@vertex", "@fragment"}; + static const char* end_markers[2] = {"@vs_end", "@fs_end"}; + static const char* version_statement = "#version 330\n"; + + char* parsed_total = NULL; + + int start_idx = TextFindIndex(shader_source, start_markers[shader_step]); + if (start_idx == BLANK_DEFAULT){ + TRACELOG(LOG_ERROR, "%s could not be found.", start_markers[shader_step]); + goto parse_err; + } + start_idx += TextLength(start_markers[shader_step]); + + int end_idx = TextFindIndex(shader_source, end_markers[shader_step]); + if (end_idx == BLANK_DEFAULT){ + TRACELOG(LOG_ERROR, "%s could not be found. Don't forget to end blocks!", end_markers[shader_step]); + goto parse_err; + } + + int block_sz = end_idx - start_idx; + + const char* block = TextSubtext(shader_source, start_idx, block_sz); + + int total_block_size = block_sz + TextLength(version_statement); + + parsed_total = (char*)RL_MALLOC(total_block_size + NULL_TERM_SZ); + + int cursor = 0; + TextAppend(parsed_total, version_statement, &cursor); + TextAppend(parsed_total, block, &cursor); + +parse_err: + return parsed_total; +} + +static Shader load_joined_shader(const char* path) +{ + Shader something = (Shader){0}; + + char* shr = LoadFileText(path); + + char* vs = shader_block_preprocess(shr, VERTEX); + if(vs == NULL){ + TRACELOG(LOG_ERROR, "Unsuccessful vertex shader parse for %s", path); + goto vertex_err; + } + + char* fs = shader_block_preprocess(shr, FRAGMENT); + if(fs == NULL){ + TRACELOG(LOG_ERROR, "Unsuccessful fragment shader parse for %s", path); + goto frag_err; + } + + something = LoadShaderFromMemory(vs, fs); + + RL_FREE(fs); +frag_err: + RL_FREE(vs); + +vertex_err: + UnloadFileText(shr); + + return something; +} + +static Shader shader_slots[MAX_SHADER_SIZE] = {0}; + +void init_shader_sys(void) +{ + for(int i = 0; i < MAX_SHADER_SIZE; ++i){ + shader_slots[i] = (Shader){0}; + } +} + +int load_new_shader(const char* path) +{ + int current_idx = BLANK_DEFAULT; + for(int i = 0; i < MAX_SHADER_SIZE; ++i){ + if(shader_slots[i].id <= 0){ + current_idx = i; + shader_slots[current_idx] = load_joined_shader(path); + break; + } + } + //TODO: Handle slots a bit better. + if(current_idx == BLANK_DEFAULT) + TRACELOG(LOG_WARNING, "Warning: No more empty shader slots.\n"); + + return current_idx; +} + +void set_active_shader(int idx) +{ + if(idx < 0 || idx >= MAX_SHADER_SIZE) + TRACELOG(LOG_WARNING,"Bounds check: Attempted to set shader at non-existent index %i.\n", idx); + else + BeginShaderMode(shader_slots[idx]); +} + +void reset_active_shader(void) +{ + EndShaderMode(); +} + +void unload_shader(int idx) +{ + if(idx < 0 || idx >= MAX_SHADER_SIZE){ + TRACELOG(LOG_WARNING,"Bounds check: Attempted to unload shader at non-existent index %i.\n", idx); + return; + } + + UnloadShader(shader_slots[idx]); + shader_slots[idx] = (Shader){0}; +} + +void unload_active_shaders(void) +{ + for(int i = 0; i < MAX_SHADER_SIZE; ++i){ + if(shader_slots[i].id > 0) + unload_shader(i); + } +}
\ No newline at end of file |
