#include "resources.h" static GHashTable *programs; static GHashTable *textures; unsigned int resources_load_program (const char *v_path, const char *f_path) { FILE *v_file = fopen (v_path, "r"); if (v_file == NULL) { WARN ("File `%s' does not exist.", v_path); return 0; } fseek (v_file, 0L, SEEK_END); size_t v_len = ftell (v_file) + 1; char *v_src = calloc (v_len, sizeof (char)); rewind (v_file); INFO ("Read %zu bytes from vertex source.", fread (v_src, sizeof (char), v_len, v_file)); FILE *f_file = fopen (f_path, "r"); if (f_file == NULL) { WARN ("File `%s' does not exist.", f_path); return 0; } fseek (f_file, 0L, SEEK_END); size_t f_len = ftell (f_file) + 1; char *f_src = calloc (f_len, sizeof (char)); rewind (f_file); INFO ("Read %zu bytes from fragment source.", fread (f_src, sizeof (char), f_len, f_file)); unsigned int program = program_create (v_src, f_src); free (v_src); free (f_src); return program; } unsigned int resources_load_texture (const char *path) { SDL_Surface *surface = IMG_Load (path); if (surface == NULL) { WARN ("Failed to load texture from path %s: %s", path, SDL_GetError ()); return 0; } unsigned int texture = texture_create (surface->w, surface->h, surface->pixels); return texture; } static inline void resources_add_program (char *key, unsigned int program) { if (program) { g_hash_table_insert (programs, key, GINT_TO_POINTER (program)); } } static inline void resources_add_texture (char *key, unsigned int texture) { if (texture) { g_hash_table_insert (textures, key, GINT_TO_POINTER (texture)); } } unsigned int resources_get_program (char *key) { if (!g_hash_table_contains (programs, key)) { WARN ("Program `%s' does not exist. Careful!", key); } return GPOINTER_TO_INT (g_hash_table_lookup (programs, key)); } unsigned int resources_get_texture (char *key) { if (!g_hash_table_contains (textures, key)) { WARN ("Texture `%s' does not exist. Careful!", key); } return GPOINTER_TO_INT (g_hash_table_lookup (textures, key)); } void res_mat4_internal (gpointer key, gpointer value, gpointer userdata) { UNUSED (key); unsigned int program = GPOINTER_TO_INT (value); struct { const char *name; mat4 *mat; } *data = userdata; program_use (program); program_set_mat4 (program, data->name, *data->mat); } void res_float_internal (gpointer key, gpointer value, gpointer userdata) { UNUSED (key); unsigned int program = GPOINTER_TO_INT (value); struct { const char *name; float val; } *data = userdata; program_use (program); program_set_float (program, data->name, data->val); } void resources_programs_set_float (const char *name, float value) { struct { const char *name; float val; } data = { name, value }; g_hash_table_foreach (programs, res_float_internal, &data); } void resources_programs_set_mat4 (const char *name, mat4 *value) { struct { const char *name; mat4 *mat; } data = { name, value }; g_hash_table_foreach (programs, res_mat4_internal, &data); } void resources_init () { programs = g_hash_table_new (g_str_hash, g_str_equal); textures = g_hash_table_new (g_str_hash, g_str_equal); #define RAP resources_add_program #define RLP resources_load_program #define RAT resources_add_texture #define RLT resources_load_texture RAP ("default", RLP ("res/shaders/default.vert", "res/shaders/default.frag")); RAP ("chunk", RLP ("res/shaders/chunk.vert", "res/shaders/chunk.frag")); RAP ("clouds", RLP ("res/shaders/clouds.vert", "res/shaders/clouds.frag")); RAP ("uielement", RLP ("res/shaders/uielement.vert", "res/shaders/uielement.frag")); RAP ("uitext", RLP ("res/shaders/uitext.vert", "res/shaders/uitext.frag")); RAT ("terrain0", RLT ("res/textures/dirt.png")); RAT ("terrain1", RLT ("res/textures/drygrass.png")); RAT ("terrain2", RLT ("res/textures/grass.png")); RAT ("terrain3", RLT ("res/textures/rock_cement.png")); RAT ("terrain4", RLT ("res/textures/asphalt_gravel.png")); RAT ("tree0", RLT ("res/textures/tree.png")); RAT ("grass0", RLT ("res/textures/grass0.png")); RAT ("clouds", RLT ("res/textures/clouds.png")); RAT ("font0", RLT ("res/textures/font.png")); #undef RAP #undef RLP #undef RAT #undef RLT program_use (RESPRG ("chunk")); program_set_int_array (RESPRG ("chunk"), "materials", 5, (int[5]) { 0, 1, 2, 3, 4 }); }