aboutsummaryrefslogtreecommitdiff
path: root/src/shader_sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_sys.c')
-rw-r--r--src/shader_sys.c139
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