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 | |
lol
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 33 | ||||
| -rw-r--r-- | src/shader_sys.c | 139 | ||||
| -rw-r--r-- | src/shader_sys.h | 13 | ||||
| -rw-r--r-- | src/texture_sys.c | 82 | ||||
| -rw-r--r-- | src/texture_sys.h | 13 | ||||
| -rw-r--r-- | src/utils.h | 8 |
6 files changed, 288 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..9bcf6f1 --- /dev/null +++ b/src/main.c @@ -0,0 +1,33 @@ +#include <raylib.h> +#include "texture_sys.h" +#include "shader_sys.h" + +int main() +{ + InitWindow(640, 480, "Gunner Engine"); + + SetTargetFPS(60); + + init_tex_sys(); + init_shader_sys(); + + int femme = load_new_tex("assets/femme.png"); + int grayscale = load_new_shader("assets/gs_full.glsl"); + + while(!WindowShouldClose()){ + update_textures(); + ClearBackground(WHITE); + BeginDrawing(); + DrawText("Wow, boilerplate, my favorite.", 4, 4, 20, BLACK); + set_active_shader(grayscale); + draw_texture(femme, 40, 40); + reset_active_shader(); + EndDrawing(); + } + + unload_active_textures(); + unload_active_shaders(); + + CloseWindow(); + return 0; +}
\ No newline at end of file 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 diff --git a/src/shader_sys.h b/src/shader_sys.h new file mode 100644 index 0000000..114e53d --- /dev/null +++ b/src/shader_sys.h @@ -0,0 +1,13 @@ +#pragma once + +void init_shader_sys(void); + +int load_new_shader(const char* path); + +void set_active_shader(int idx); + +void reset_active_shader(void); + +void unload_shader(int idx); + +void unload_active_shaders(void);
\ No newline at end of file diff --git a/src/texture_sys.c b/src/texture_sys.c new file mode 100644 index 0000000..170e124 --- /dev/null +++ b/src/texture_sys.c @@ -0,0 +1,82 @@ +#include "utils.h" + +#include <stddef.h> + +#define MAX_TEX_SIZE 16 + +static Texture2D texture_slots[MAX_TEX_SIZE] = {0}; +static long texture_modtimes[MAX_TEX_SIZE] = {0}; +static const char* texture_paths[MAX_TEX_SIZE] = {0}; + +void init_tex_sys(void) +{ + for(int i = 0; i < MAX_TEX_SIZE; ++i){ + texture_slots[i] = (Texture2D){0}; + texture_modtimes[i] = BLANK_DEFAULT; + texture_paths[i] = NULL; + } +} + +int load_new_tex(const char* path) +{ + int current_idx = BLANK_DEFAULT; + for(int i = 0; i < MAX_TEX_SIZE; ++i){ + if(texture_slots[i].id <= 0){ + current_idx = i; + texture_slots[current_idx] = LoadTexture(path); + texture_modtimes[current_idx] = GetFileModTime(path); + texture_paths[current_idx] = path; + break; + } + } + //TODO: Handle slots a bit better. + if(current_idx == BLANK_DEFAULT) + TRACELOG(LOG_WARNING, "Warning: No more empty texture slots.\n"); + + return current_idx; +} + +void draw_texture(int idx, int x, int y) +{ + if(idx < 0 || idx >= MAX_TEX_SIZE){ + TRACELOG(LOG_WARNING,"Bounds check: Attempted to draw texture from non-existent index %i.\n", idx); + return; + } + DrawTexture(texture_slots[idx], x, y, WHITE); +} + +void update_textures(void) +{ + for(int i = 0; i < MAX_TEX_SIZE; ++i){ + if(texture_slots[i].id > 0){ + long current_mod = GetFileModTime(texture_paths[i]); + + if(current_mod != texture_modtimes[i]){ + texture_modtimes[i] = current_mod; + + UnloadTexture(texture_slots[i]); + texture_slots[i] = LoadTexture(texture_paths[i]); + } + } + } +} + +void unload_tex(int idx) +{ + if(idx < 0 || idx >= MAX_TEX_SIZE){ + TRACELOG(LOG_WARNING,"Bounds check: Attempted to unload texture from non-existent index %i.\n", idx); + return; + } + UnloadTexture(texture_slots[idx]); + texture_slots[idx] = (Texture2D){0}; + texture_modtimes[idx] = BLANK_DEFAULT; + texture_paths[idx] = NULL; +} + +void unload_active_textures(void) +{ + for(int i = 0; i < MAX_TEX_SIZE; ++i){ + if(texture_slots[i].id > 0) + unload_tex(i); + } +} diff --git a/src/texture_sys.h b/src/texture_sys.h new file mode 100644 index 0000000..67c9e19 --- /dev/null +++ b/src/texture_sys.h @@ -0,0 +1,13 @@ +#pragma once + +void init_tex_sys(void); + +int load_new_tex(const char* path); + +void draw_texture(int idx, int x, int y); + +void update_textures(void); + +void unload_tex(int idx); + +void unload_active_textures(void); diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..2d367d0 --- /dev/null +++ b/src/utils.h @@ -0,0 +1,8 @@ +#pragma once + +#include <raylib.h> +#define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__) + +#define BLANK_DEFAULT -1 +#define NULL_TERM '\0' +#define NULL_TERM_SZ 1
\ No newline at end of file |
