Files
wschod/game/src/resources.c
T

186 lines
4.5 KiB
C

#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 });
}