diff options
| author | tech kaczynski <tk@techkaczynski.dev> | 2026-09-22 22:38:57 +1000 |
|---|---|---|
| committer | tech kaczynski <tk@techkaczynski.dev> | 2026-09-22 22:38:57 +1000 |
| commit | 08cb8d6a585dd552b69a488d9db1be123f01467a (patch) | |
| tree | 77d50ce30bbc102b08486929ba654b5bef70af43 /res.c | |
initial commit.
Diffstat (limited to 'res.c')
| -rw-r--r-- | res.c | 251 |
1 files changed, 251 insertions, 0 deletions
@@ -0,0 +1,251 @@ +#include "res.h" +#include "raygui.h" + +typedef struct { + map_t(Asset) assets; + map_t(FunShader) sdr; +} Resources; + +static Resources res = {0}; + +static bool +asset_load_data(cstr key) { + Asset *asset = map_get(&res.assets, key); + cstr ext = GetFileExtension(key); + bool success = false; + + if (!strcmp(ext, ".glb")) { + Model mdl = LoadModel(key); + + if (!IsModelValid(mdl)) { + UnloadModel(mdl); + return false; + } + + for (int i = 0; i < mdl.materialCount; ++i) { + mdl.materials[i].shader = shader_get("model")->sdr; + } + + asset->tag = ASSET_TAG_MODEL; + asset->mdl = mdl; + success = true; + } + + if (!strcmp(ext, ".png")) { + Texture tex = LoadTexture(key); + + if (!IsTextureValid(tex)) { + UnloadTexture(tex); + return false; + } + + GenTextureMipmaps(&tex); + // SetTextureFilter(tex, TEXTURE_FILTER_ANISOTROPIC_16X); + SetTextureFilter(tex, TEXTURE_FILTER_TRILINEAR); + // SetTextureFilter(tex, TEXTURE_FILTER_BILINEAR); + + asset->tag = ASSET_TAG_TEXTURE; + asset->tex = tex; + success = true; + } + + if (!strcmp(ext, ".ttf") || !strcmp(ext, ".otf")) { + Font fnt = LoadFont(key); + + if (!IsFontValid(fnt)) { + UnloadFont(fnt); + return false; + } + + asset->tag = ASSET_TAG_FONT; + asset->fnt = fnt; + success = true; + } + + if (!strcmp(ext, ".ogg")) { + Sound snd = LoadSound(key); + + if (!IsSoundValid(snd)) { + UnloadSound(snd); + return false; + } + + asset->tag = ASSET_TAG_SOUND; + asset->snd = snd; + success = true; + } + + if (!success) { + TraceLog(LOG_WARNING, "'%s' no valid file ext found.", key); + return false; + } + + asset->loaded = true; + return true; +} + +static void +asset_unload(cstr key) { + Asset *asset = map_get(&res.assets, key); + if (!asset) { + TraceLog(LOG_WARNING, + "asset_unload: invalid key '%s'\n", key); + return; + } + + if (!asset->loaded) { + TraceLog(LOG_INFO, + "asset_unload: nothing to unload '%s'", key); + return; + } + + free(asset->path); + asset->path_strlen = 0; + + switch(asset->tag) { + case ASSET_TAG_MODEL: + UnloadModel(asset->mdl); + break; + case ASSET_TAG_TEXTURE: + UnloadTexture(asset->tex); + break; + case ASSET_TAG_SOUND: + UnloadSound(asset->snd); + break; + case ASSET_TAG_FONT: + UnloadFont(asset->fnt); + break; + case ASSET_TAG_INVALID: + TraceLog(LOG_WARNING, + "asset_unload: invalid tag '%s'\n", key); + break; + } +} + +void +res_init(void) { + map_init(&res.sdr); + map_init(&res.assets); + + fun_shader_create("model", + "res/sdr/mdl_vtx_lit.vs", + "res/sdr/mdl_vtx_lit.fs"); + + fun_shader_create("sky", NULL, "res/sdr/sky.fs"); + + cstr filter = ".glb;.png;.ttf;.otf;.ogg"; + FilePathList res_list = LoadDirectoryFilesEx("res", filter, true); + + for (int i = 0; i < res_list.count; ++i) { + cstr path = res_list.paths[i]; + Asset asset = {0}; + asset.path_strlen = strlen(path); + asset.path = strdup(path); // freed in asset_unload + map_set(&res.assets, asset.path, asset); + } + + UnloadDirectoryFiles(res_list); +} + +void +res_exit(void) { + cstr key; + map_iter_t iter; + + iter = map_iter(&res.assets); + while ((key = map_next(&res.assets, &iter))) { + asset_unload(key); + } + + iter = map_iter(&res.sdr); + while ((key = map_next(&res.sdr, &iter))) { + FunShader *sdr = map_get(&res.sdr, key); + if (!sdr) { + TraceLog(LOG_ERROR, "res_exit: '%s' invalid\n", key); + } + fun_shader_delete(sdr); + } + + map_deinit(&res.assets); + map_deinit(&res.sdr); +} + +void +res_update(void) { +} + +Asset* +asset_get(cstr key) { + Asset *asset = map_get(&res.assets, key); + if (!asset) { + TraceLog(LOG_ERROR, "asset '%s' not found.\n", key); + return NULL; + } + + if (!asset->loaded) { + if (!asset_load_data(key)) { + TraceLog(LOG_ERROR, "asset '%s' couldn't load.", key); + return NULL; + } + } + + return asset; +} + +FunShader* +shader_get(cstr key) { + FunShader *sdr = map_get(&res.sdr, key); + if (!sdr) { + TraceLog(LOG_ERROR, "shader '%s' not found.", key); + return NULL; + } + return sdr; +} + +void +fun_shader_create(cstr key, cstr vpath, cstr fpath) { + FunShader shader = {0}; + shader.sdr = LoadShader(vpath, fpath); + if (!IsShaderValid(shader.sdr)) { + printf("err: fun_shader_create('%s', '%s', '%s')\n", + key, vpath, fpath); + exit(1); + } + map_init(&shader.uniforms); + map_set(&res.sdr, key, shader); +} + +void +fun_shader_delete(FunShader *shader) { + UnloadShader(shader->sdr); + map_deinit(&shader->uniforms); +} + +int +fun_shader_uniform(cstr skey, cstr ukey) { + FunShader *sdr = shader_get(skey); + + int *ret = map_get(&sdr->uniforms, ukey); + if (ret) { + return *ret; + } + + BeginShaderMode(sdr->sdr); + int loc = rlGetLocationUniform(sdr->sdr.id, ukey); + if (loc < 0) { + TraceLog(LOG_ERROR, + "shader '%s' uniform '%s' not found.\n", skey, ukey); + exit(1); + } + EndShaderMode(); + + map_set(&sdr->uniforms, ukey, loc); + ret = map_get(&sdr->uniforms, ukey); + if (!ret) { + TraceLog(LOG_ERROR, + "shader '%s' uniform '%s' not found", skey, ukey); + return -1; + } + + return *ret; +} |
