Remove the billions of structs and globals
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
||||
SRC=src/main.c src/program.c src/resources.c src/camera.c src/chunk/chunk.c \
|
||||
SRC=src/main.c src/program.c src/res.c src/camera.c src/chunk/chunk.c \
|
||||
src/chunk/mesh.c src/flags.c src/texture.c src/chunk/manager.c \
|
||||
src/event/manager.c src/event/handlers.c src/state.c src/graphics.c \
|
||||
src/entity/meshes.c src/entity/manager.c src/entity/templates.c
|
||||
|
||||
+14
-31
@@ -1,54 +1,37 @@
|
||||
#include "camera.h"
|
||||
|
||||
Camera
|
||||
Camera_default ()
|
||||
{
|
||||
Camera cam = {
|
||||
.position = { 0.0f, 0.0f, 0.0f },
|
||||
.rotation = { 0.0f, 0.0f, 0.0f },
|
||||
.fov = 80,
|
||||
.near = 0.1,
|
||||
.far = 1000.0
|
||||
};
|
||||
|
||||
return cam;
|
||||
}
|
||||
vec3 camera_position;
|
||||
vec3 camera_rotation;
|
||||
|
||||
void
|
||||
Camera_get_direction (Camera *camera, vec3 dest)
|
||||
camera_get_direction (vec3 dest)
|
||||
{
|
||||
dest[0] = sinf (camera->rotation[0]) * cosf (camera->rotation[1]);
|
||||
dest[1] = sinf (camera->rotation[1]);
|
||||
dest[2] = cosf (camera->rotation[0]) * cosf (camera->rotation[1]);
|
||||
dest[0] = sinf (camera_rotation[0]) * cosf (camera_rotation[1]);
|
||||
dest[1] = sinf (camera_rotation[1]);
|
||||
dest[2] = cosf (camera_rotation[0]) * cosf (camera_rotation[1]);
|
||||
glm_vec3_normalize (dest);
|
||||
}
|
||||
|
||||
void
|
||||
Camera_get_right (Camera *camera, vec3 dest)
|
||||
camera_get_right (vec3 dest)
|
||||
{
|
||||
vec3 dir;
|
||||
Camera_get_direction (camera, dir);
|
||||
camera_get_direction (dir);
|
||||
glm_vec3_cross (dir, GLM_YUP, dest);
|
||||
glm_vec3_normalize (dest);
|
||||
}
|
||||
|
||||
void
|
||||
Camera_get_view (Camera *camera, mat4 dest)
|
||||
camera_get_view (mat4 dest)
|
||||
{
|
||||
vec3 dir, center;
|
||||
Camera_get_direction (camera, dir);
|
||||
glm_vec3_add (camera->position, dir, center);
|
||||
glm_lookat (camera->position, center, GLM_YUP, dest);
|
||||
camera_get_direction (dir);
|
||||
glm_vec3_add (camera_position, dir, center);
|
||||
glm_lookat (camera_position, center, GLM_YUP, dest);
|
||||
}
|
||||
|
||||
void
|
||||
Camera_get_projection (Camera *camera, float aspect, mat4 dest)
|
||||
camera_get_projection (float aspect, mat4 dest)
|
||||
{
|
||||
glm_perspective (DEGTORAD (camera->fov), aspect, camera->near, camera->far, dest);
|
||||
}
|
||||
|
||||
void
|
||||
Camera_print (Camera *camera)
|
||||
{
|
||||
INFO ("Camera position: (%6.1f, %6.1f, %6.1f)", camera->position[0], camera->position[1], camera->position[2]);
|
||||
glm_perspective (glm_rad (90), aspect, 0.1, 1000.0, dest);
|
||||
}
|
||||
|
||||
+4
-16
@@ -4,19 +4,7 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
typedef struct Camera
|
||||
{
|
||||
vec3 position;
|
||||
vec3 rotation;
|
||||
int fov;
|
||||
float near;
|
||||
float far;
|
||||
} Camera;
|
||||
|
||||
Camera Camera_default ();
|
||||
|
||||
void Camera_get_direction (Camera *camera, vec3 dest);
|
||||
void Camera_get_right (Camera *camera, vec3 dest);
|
||||
void Camera_get_view (Camera *camera, mat4 dest);
|
||||
void Camera_get_projection (Camera *camera, float aspect, mat4 dest);
|
||||
void Camera_print (Camera *camera);
|
||||
void camera_get_direction (vec3 dest);
|
||||
void camera_get_right (vec3 dest);
|
||||
void camera_get_view (mat4 dest);
|
||||
void camera_get_projection (float aspect, mat4 dest);
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
extern GHashTable *entity_templates;
|
||||
extern GSequence *entity_manager;
|
||||
|
||||
Chunk *
|
||||
Chunk_new ()
|
||||
{
|
||||
@@ -31,22 +28,22 @@ Chunk_random (Chunk *chunk, int xoffset, int zoffset)
|
||||
if (rand() % 100 < 2)
|
||||
{
|
||||
Entity *tree = malloc (sizeof (Entity));
|
||||
*tree = ET_ENTGET ("tree");
|
||||
*tree = ETEMPLGET ("tree");
|
||||
tree->position[0] = x + xoffset;
|
||||
tree->position[1] = chunk->heightmap [INDEX (x, z)];
|
||||
tree->position[2] = z + zoffset;
|
||||
tree->rotation = rand () % 180;
|
||||
EM_ENTADD (tree);
|
||||
em_add_entity (tree);
|
||||
}
|
||||
|
||||
if (rand() % 100 < 10)
|
||||
{
|
||||
Entity *grass = malloc (sizeof (Entity));
|
||||
*grass = ET_ENTGET ("grass");
|
||||
*grass = ETEMPLGET ("grass");
|
||||
grass->position[0] = x + xoffset;
|
||||
grass->position[1] = chunk->heightmap [INDEX (x, z)];
|
||||
grass->position[2] = z + zoffset;
|
||||
EM_ENTADD (grass);
|
||||
em_add_entity (grass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
-29
@@ -3,7 +3,8 @@
|
||||
/* TODO: perhaps render the chunks in a circle, not a square, around
|
||||
the player? */
|
||||
|
||||
ChunkManager chunk_manager;
|
||||
static GHashTable *chunks;
|
||||
static GHashTable *chunk_meshes;
|
||||
|
||||
guint
|
||||
cm_ivec2_hash (gconstpointer key)
|
||||
@@ -37,17 +38,17 @@ cm_world_to_chunk (float x, float z, int *ox, int *oz)
|
||||
}
|
||||
|
||||
void
|
||||
ChunkManager_init ()
|
||||
cm_init ()
|
||||
{
|
||||
chunk_manager.chunks = g_hash_table_new_full (cm_ivec2_hash, cm_ivec2_equal, free, (GDestroyNotify) Chunk_free);
|
||||
chunk_manager.chunk_meshes = g_hash_table_new_full (cm_ivec2_hash, cm_ivec2_equal, free, (GDestroyNotify) Chunk_free);
|
||||
chunks = g_hash_table_new_full (cm_ivec2_hash, cm_ivec2_equal, free, (GDestroyNotify) Chunk_free);
|
||||
chunk_meshes = g_hash_table_new_full (cm_ivec2_hash, cm_ivec2_equal, free, (GDestroyNotify) Chunk_free);
|
||||
}
|
||||
|
||||
/* TODO: Update the chunks only if the player has moved into another
|
||||
chunk, to save frame time. */
|
||||
|
||||
void
|
||||
ChunkManager_update (vec3 camera_position)
|
||||
cm_update (vec3 camera_position)
|
||||
{
|
||||
int cx, cz;
|
||||
cm_world_to_chunk (camera_position[0], camera_position[2], &cx, &cz);
|
||||
@@ -56,9 +57,9 @@ ChunkManager_update (vec3 camera_position)
|
||||
{
|
||||
for (int x = cx - RENDER_DISTANCE - 1; x <= cx + RENDER_DISTANCE + 1; ++x)
|
||||
{
|
||||
if (ChunkManager_get_Chunk_at (x, z) == NULL)
|
||||
if (cm_get_Chunk_at (x, z) == NULL)
|
||||
{
|
||||
ChunkManager_generate_Chunk_at (x, z);
|
||||
cm_generate_Chunk_at (x, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,16 +68,16 @@ ChunkManager_update (vec3 camera_position)
|
||||
{
|
||||
for (int x = cx - RENDER_DISTANCE; x <= cx + RENDER_DISTANCE; ++x)
|
||||
{
|
||||
if (ChunkManager_get_ChunkMesh_at (x, z) == NULL)
|
||||
if (cm_get_ChunkMesh_at (x, z) == NULL)
|
||||
{
|
||||
ChunkManager_generate_ChunkMesh_at (x, z);
|
||||
cm_generate_ChunkMesh_at (x, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChunkManager_render (vec3 camera_position, int program)
|
||||
cm_render (vec3 camera_position, int program)
|
||||
{
|
||||
int cx = 0, cz = 0;
|
||||
cm_world_to_chunk (camera_position[0], camera_position[2], &cx, &cz);
|
||||
@@ -85,7 +86,7 @@ ChunkManager_render (vec3 camera_position, int program)
|
||||
{
|
||||
for (int x = cx - RENDER_DISTANCE; x <= cx + RENDER_DISTANCE; ++x)
|
||||
{
|
||||
ChunkMesh *mesh = ChunkManager_get_ChunkMesh_at (x, z);
|
||||
ChunkMesh *mesh = cm_get_ChunkMesh_at (x, z);
|
||||
if (mesh != NULL)
|
||||
{
|
||||
program_set_vec3 (program, "chunk_position", x * CHUNK_DIM, 0.0, z * CHUNK_DIM);
|
||||
@@ -96,50 +97,50 @@ ChunkManager_render (vec3 camera_position, int program)
|
||||
}
|
||||
|
||||
Chunk *
|
||||
ChunkManager_get_Chunk_at (int x, int z)
|
||||
cm_get_Chunk_at (int x, int z)
|
||||
{
|
||||
return (Chunk *) g_hash_table_lookup (chunk_manager.chunks, (ivec2) { x, z });
|
||||
return (Chunk *) g_hash_table_lookup (chunks, (ivec2) { x, z });
|
||||
}
|
||||
|
||||
void
|
||||
ChunkManager_set_Chunk_at (int x, int z, Chunk *chunk)
|
||||
cm_set_Chunk_at (int x, int z, Chunk *chunk)
|
||||
{
|
||||
g_hash_table_insert (chunk_manager.chunks, cm_make_key (x, z), chunk);
|
||||
g_hash_table_insert (chunks, cm_make_key (x, z), chunk);
|
||||
}
|
||||
|
||||
void
|
||||
ChunkManager_generate_Chunk_at (int x, int z)
|
||||
cm_generate_Chunk_at (int x, int z)
|
||||
{
|
||||
Chunk *chunk = Chunk_new ();
|
||||
Chunk_random (chunk, x * CHUNK_DIM, z * CHUNK_DIM);
|
||||
ChunkManager_set_Chunk_at (x, z, chunk);
|
||||
cm_set_Chunk_at (x, z, chunk);
|
||||
}
|
||||
|
||||
void
|
||||
ChunkManager_get_Chunk_neighbors_at (int x, int z, Chunk **nr, Chunk **nd, Chunk **nc)
|
||||
cm_get_Chunk_neighbors_at (int x, int z, Chunk **nr, Chunk **nd, Chunk **nc)
|
||||
{
|
||||
*nr = ChunkManager_get_Chunk_at (x + 1, z);
|
||||
*nd = ChunkManager_get_Chunk_at (x, z + 1);
|
||||
*nc = ChunkManager_get_Chunk_at (x + 1, z + 1);
|
||||
*nr = cm_get_Chunk_at (x + 1, z);
|
||||
*nd = cm_get_Chunk_at (x, z + 1);
|
||||
*nc = cm_get_Chunk_at (x + 1, z + 1);
|
||||
}
|
||||
|
||||
ChunkMesh *
|
||||
ChunkManager_get_ChunkMesh_at (int x, int z)
|
||||
cm_get_ChunkMesh_at (int x, int z)
|
||||
{
|
||||
return (ChunkMesh *) g_hash_table_lookup (chunk_manager.chunk_meshes, (ivec2) { x, z });
|
||||
return (ChunkMesh *) g_hash_table_lookup (chunk_meshes, (ivec2) { x, z });
|
||||
}
|
||||
|
||||
void
|
||||
ChunkManager_set_ChunkMesh_at (int x, int z, ChunkMesh *mesh)
|
||||
cm_set_ChunkMesh_at (int x, int z, ChunkMesh *mesh)
|
||||
{
|
||||
g_hash_table_insert (chunk_manager.chunk_meshes, cm_make_key (x, z), mesh);
|
||||
g_hash_table_insert (chunk_meshes, cm_make_key (x, z), mesh);
|
||||
}
|
||||
|
||||
void
|
||||
ChunkManager_generate_ChunkMesh_at (int x, int z)
|
||||
cm_generate_ChunkMesh_at (int x, int z)
|
||||
{
|
||||
Chunk *nr, *nd, *nc;
|
||||
ChunkManager_get_Chunk_neighbors_at (x, z, &nr, &nd, &nc);
|
||||
ChunkManager_set_ChunkMesh_at
|
||||
(x, z, ChunkMesh_build (ChunkManager_get_Chunk_at (x, z), nr, nd, nc));
|
||||
cm_get_Chunk_neighbors_at (x, z, &nr, &nd, &nc);
|
||||
cm_set_ChunkMesh_at
|
||||
(x, z, ChunkMesh_build (cm_get_Chunk_at (x, z), nr, nd, nc));
|
||||
}
|
||||
|
||||
+10
-19
@@ -9,25 +9,16 @@
|
||||
|
||||
#define RENDER_DISTANCE 3
|
||||
|
||||
typedef struct ChunkManager
|
||||
{
|
||||
GHashTable *chunks;
|
||||
GHashTable *chunk_meshes;
|
||||
void cm_init ();
|
||||
void cm_update (vec3 camera_position);
|
||||
void cm_render (vec3 camera_position, int program);
|
||||
|
||||
GAsyncQueue *chunk_queue;
|
||||
GAsyncQueue *chunk_mesh_queue;
|
||||
} ChunkManager;
|
||||
Chunk *cm_get_Chunk_at (int x, int z);
|
||||
void cm_get_Chunk_neighbors_at (int x, int z, Chunk **nr, Chunk **nd, Chunk **nc);
|
||||
void cm_set_Chunk_at (int x, int z, Chunk *chunk);
|
||||
|
||||
void ChunkManager_init ();
|
||||
void ChunkManager_update (vec3 camera_position);
|
||||
void ChunkManager_render (vec3 camera_position, int program);
|
||||
ChunkMesh *cm_get_ChunkMesh_at (int x, int z);
|
||||
void cm_set_ChunkMesh_at (int x, int z, ChunkMesh *mesh);
|
||||
|
||||
Chunk *ChunkManager_get_Chunk_at (int x, int z);
|
||||
void ChunkManager_get_Chunk_neighbors_at (int x, int z, Chunk **nr, Chunk **nd, Chunk **nc);
|
||||
void ChunkManager_set_Chunk_at (int x, int z, Chunk *chunk);
|
||||
|
||||
ChunkMesh *ChunkManager_get_ChunkMesh_at (int x, int z);
|
||||
void ChunkManager_set_ChunkMesh_at (int x, int z, ChunkMesh *mesh);
|
||||
|
||||
void ChunkManager_generate_Chunk_at (int x, int z);
|
||||
void ChunkManager_generate_ChunkMesh_at (int x, int z);
|
||||
void cm_generate_Chunk_at (int x, int z);
|
||||
void cm_generate_ChunkMesh_at (int x, int z);
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
/* No need to bind the elements buffer all the time; it's the same for
|
||||
every single ChunkMesh. */
|
||||
|
||||
extern GameFlags game_flags;
|
||||
|
||||
ChunkMesh *
|
||||
ChunkMesh_build (Chunk *chunk, Chunk *nr, Chunk *nd, Chunk *nc)
|
||||
/* nd --- down neighbor; nr --- right neighbor; nc --- corner neighbor */
|
||||
@@ -110,7 +108,7 @@ ChunkMesh_render (ChunkMesh *mesh)
|
||||
|
||||
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->ebo);
|
||||
|
||||
if (game_flags.wireframe_enabled)
|
||||
if (flags_get ("wireframe_enabled"))
|
||||
{
|
||||
glDrawElements (GL_LINES, CHUNK_SIZE * 6, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
+48
-22
@@ -1,21 +1,15 @@
|
||||
#include "manager.h"
|
||||
|
||||
/* TODO: Sort entities by mesh type AS WELL AS distance. Binding
|
||||
buffers is very performance-sensitive, thus to conserve speed one
|
||||
type should be rendered in one go, then the other type, etc. */
|
||||
extern vec3 camera_position;
|
||||
|
||||
GSequence *entity_manager;
|
||||
EntityMesh mesh_quad2, mesh_quad_x;
|
||||
|
||||
extern GameState game_state;
|
||||
extern Resources resources;
|
||||
|
||||
unsigned int last_type = -1;
|
||||
static GSequence *entities;
|
||||
static EntityMesh mesh_quad2, mesh_quad_x;
|
||||
static unsigned int last_type = -1;
|
||||
|
||||
void
|
||||
EntityManager_init ()
|
||||
em_init ()
|
||||
{
|
||||
entity_manager = g_sequence_new (NULL);
|
||||
entities = g_sequence_new (NULL);
|
||||
mesh_quad2 = EntityMesh_make_quad2 ();
|
||||
mesh_quad_x = EntityMesh_make_quad_x ();
|
||||
}
|
||||
@@ -33,9 +27,9 @@ em_tick_internal (gpointer data, gpointer userdata)
|
||||
}
|
||||
|
||||
void
|
||||
EntityManager_tick ()
|
||||
em_tick ()
|
||||
{
|
||||
g_sequence_foreach (entity_manager, em_tick_internal, NULL);
|
||||
g_sequence_foreach (entities, em_tick_internal, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -44,7 +38,7 @@ em_render_internal (gpointer data, gpointer userdata)
|
||||
Entity *entity = data;
|
||||
mat4 *view = userdata;
|
||||
|
||||
if (glm_vec3_distance (game_state.camera.position, entity->position) > EM_RENDER_DISTANCE)
|
||||
if (glm_vec3_distance (camera_position, entity->position) > EM_RENDER_DISTANCE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -55,7 +49,7 @@ em_render_internal (gpointer data, gpointer userdata)
|
||||
vec4 planes[6];
|
||||
mat4 proj, view_proj;
|
||||
|
||||
Camera_get_projection (&game_state.camera, 640.0 / 480.0, proj);
|
||||
camera_get_projection (640.0 / 480.0, proj);
|
||||
glm_mat4_mul (proj, *view, view_proj);
|
||||
glm_frustum_planes (view_proj, planes);
|
||||
|
||||
@@ -113,7 +107,7 @@ em_render_internal (gpointer data, gpointer userdata)
|
||||
/* It's not quite a "real" billboard, but the effect is much
|
||||
better on the eye. */
|
||||
vec3 delta;
|
||||
glm_vec3_sub (game_state.camera.position, entity->position, delta);
|
||||
glm_vec3_sub (camera_position, entity->position, delta);
|
||||
delta[1] = 0.0;
|
||||
glm_normalize (delta);
|
||||
glm_rotate_at(model, entity->position, atan2f (delta[0], delta[2]), (vec3) { 0.0, 1.0, 0.0 });
|
||||
@@ -132,11 +126,10 @@ em_render_internal (gpointer data, gpointer userdata)
|
||||
|
||||
glm_scale (model, entity->scale);
|
||||
|
||||
program_use (R_PRGGET ("default"));
|
||||
program_set_mat4 (R_PRGGET ("default"), "model", model);
|
||||
program_set_mat4 (RESPRG ("default"), "model", model);
|
||||
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, R_TEXGET (entity->texture));
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX (entity->texture));
|
||||
|
||||
if (entity->mesh_type != last_type)
|
||||
{
|
||||
@@ -148,7 +141,40 @@ em_render_internal (gpointer data, gpointer userdata)
|
||||
}
|
||||
|
||||
void
|
||||
EntityManager_render (mat4 view)
|
||||
em_render (mat4 view)
|
||||
{
|
||||
g_sequence_foreach (entity_manager, em_render_internal, view);
|
||||
g_sequence_foreach (entities, em_render_internal, view);
|
||||
}
|
||||
|
||||
static inline int
|
||||
em_compare (gconstpointer a, gconstpointer b, gpointer userdata)
|
||||
/* This function is used to sort Entities by their mesh type, so that
|
||||
diferrent buffers aren't bound every single frame. */
|
||||
{
|
||||
UNUSED (userdata);
|
||||
const Entity *entity1 = a;
|
||||
const Entity *entity2 = b;
|
||||
|
||||
if (entity1->mesh_type == entity2->mesh_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (entity1->mesh_type == MESH_QUAD_X && entity2->mesh_type == MESH_QUAD2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (entity1->mesh_type == MESH_QUAD2 && entity2->mesh_type == MESH_QUAD_X)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return (int) entity1->mesh_type - (int) entity2->mesh_type;
|
||||
}
|
||||
|
||||
void
|
||||
em_add_entity (Entity *entity)
|
||||
{
|
||||
g_sequence_insert_sorted (entities, entity, em_compare, NULL);
|
||||
}
|
||||
|
||||
@@ -6,41 +6,13 @@
|
||||
#include "entity.h"
|
||||
#include "meshes.h"
|
||||
#include "../util.h"
|
||||
#include "../resources.h"
|
||||
#include "../res.h"
|
||||
#include "../state.h"
|
||||
#include "../chunk/chunk.h"
|
||||
|
||||
#define EM_RENDER_DISTANCE (3*CHUNK_DIM/2)
|
||||
|
||||
#define EM_ENTADD(entity) (g_sequence_insert_sorted (entity_manager, entity, em_compare, NULL));
|
||||
|
||||
static inline int
|
||||
em_compare (gconstpointer a, gconstpointer b, gpointer userdata)
|
||||
/* This function is used to sort Entities by their mesh type, so that
|
||||
diferrent buffers aren't bound every single frame. */
|
||||
{
|
||||
UNUSED (userdata);
|
||||
const Entity *entity1 = a;
|
||||
const Entity *entity2 = b;
|
||||
|
||||
if (entity1->mesh_type == entity2->mesh_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (entity1->mesh_type == MESH_QUAD_X && entity2->mesh_type == MESH_QUAD2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (entity1->mesh_type == MESH_QUAD2 && entity2->mesh_type == MESH_QUAD_X)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return (int) entity1->mesh_type - (int) entity2->mesh_type;
|
||||
}
|
||||
|
||||
void EntityManager_init ();
|
||||
void EntityManager_tick ();
|
||||
void EntityManager_render ();
|
||||
void em_init ();
|
||||
void em_tick ();
|
||||
void em_render ();
|
||||
void em_add_entity (Entity *entity);
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
/* TODO: Split binding/rendering */
|
||||
|
||||
extern GameFlags game_flags;
|
||||
|
||||
void
|
||||
EntityMesh_bind (EntityMesh *mesh)
|
||||
{
|
||||
@@ -21,7 +19,7 @@ EntityMesh_bind (EntityMesh *mesh)
|
||||
void
|
||||
EntityMesh_render (EntityMesh *mesh)
|
||||
{
|
||||
if (game_flags.wireframe_enabled)
|
||||
if (flags_get ("wireframe_enabled"))
|
||||
{
|
||||
glDrawElements (GL_LINES, mesh->indices_len, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
#include "templates.h"
|
||||
|
||||
GHashTable *entity_templates;
|
||||
static GHashTable *templates;
|
||||
|
||||
static inline void
|
||||
ent_templates_add (char *key, Entity *entity)
|
||||
{
|
||||
g_hash_table_insert (templates, key, entity);
|
||||
}
|
||||
|
||||
Entity
|
||||
ent_templates_get (char *key)
|
||||
{
|
||||
return *(Entity *) g_hash_table_lookup (templates, key);
|
||||
}
|
||||
|
||||
void
|
||||
EntityTemplates_init ()
|
||||
ent_templates_init ()
|
||||
{
|
||||
entity_templates = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
templates = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
Entity *tree = malloc (sizeof (Entity));
|
||||
*tree = (Entity) {
|
||||
@@ -17,7 +29,7 @@ EntityTemplates_init ()
|
||||
.texture = "tree0"
|
||||
};
|
||||
|
||||
ET_ENTADD ("tree", tree);
|
||||
ent_templates_add ("tree", tree);
|
||||
|
||||
Entity *grass = malloc (sizeof (Entity));
|
||||
*grass = (Entity) {
|
||||
@@ -30,8 +42,5 @@ EntityTemplates_init ()
|
||||
.texture = "grass0"
|
||||
};
|
||||
|
||||
ET_ENTADD ("grass", grass);
|
||||
ent_templates_add ("grass", grass);
|
||||
}
|
||||
|
||||
/* To avoid confusion with EM_ENTADD. */
|
||||
#undef ET_ENTADD
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
/* TODO: Maybe make a function that allocates an Entity for you and
|
||||
adds it's data from the template? */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib-2.0/glib.h>
|
||||
@@ -10,7 +7,7 @@
|
||||
|
||||
#include "entity.h"
|
||||
|
||||
#define ET_ENTGET(key) (*(Entity *) g_hash_table_lookup (entity_templates, key))
|
||||
#define ET_ENTADD(key, entity) (g_hash_table_insert (entity_templates, key, entity))
|
||||
#define ETEMPLGET(key) (ent_templates_get (key))
|
||||
|
||||
void EntityTemplates_init ();
|
||||
void ent_templates_init ();
|
||||
Entity ent_templates_get (char *key);
|
||||
|
||||
+16
-16
@@ -1,7 +1,7 @@
|
||||
#include "handlers.h"
|
||||
|
||||
extern GameState game_state;
|
||||
extern GameFlags game_flags;
|
||||
extern vec3 camera_position;
|
||||
extern vec3 camera_rotation;
|
||||
|
||||
void
|
||||
handlers_init ()
|
||||
@@ -13,12 +13,12 @@ handlers_init ()
|
||||
void
|
||||
handler_lookaround (SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_MOUSE_MOTION && game_flags.can_free_look)
|
||||
if (event->type == SDL_EVENT_MOUSE_MOTION)
|
||||
{
|
||||
game_state.camera.rotation[0] -= event->motion.xrel / 100.f;
|
||||
game_state.camera.rotation[1] -= event->motion.yrel / 100.f;
|
||||
game_state.camera.rotation[1] =
|
||||
CLAMP (game_state.camera.rotation[1], -M_PI / 2 + 0.025, M_PI / 2 - 0.025);
|
||||
camera_rotation[0] -= event->motion.xrel / 100.f;
|
||||
camera_rotation[1] -= event->motion.yrel / 100.f;
|
||||
camera_rotation[1] =
|
||||
CLAMP (camera_rotation[1], -M_PI / 2 + 0.025, M_PI / 2 - 0.025);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,19 +30,19 @@ handler_movement (SDL_Event *event)
|
||||
switch (event->key.key)
|
||||
{
|
||||
case SDLK_W:
|
||||
game_flags.moving_forward = 1;
|
||||
flags_set ("moving_forward", true);
|
||||
break;
|
||||
case SDLK_A:
|
||||
game_flags.moving_left = 1;
|
||||
flags_set ("moving_left", true);
|
||||
break;
|
||||
case SDLK_S:
|
||||
game_flags.moving_backward = 1;
|
||||
flags_set ("moving_backward", true);
|
||||
break;
|
||||
case SDLK_D:
|
||||
game_flags.moving_right = 1;
|
||||
flags_set ("moving_right", true);
|
||||
break;
|
||||
case SDLK_F1:
|
||||
game_flags.wireframe_enabled = !game_flags.wireframe_enabled;
|
||||
flags_set ("wireframe_enabled", !flags_get ("wireframe_enabled"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -52,16 +52,16 @@ handler_movement (SDL_Event *event)
|
||||
switch (event->key.key)
|
||||
{
|
||||
case SDLK_W:
|
||||
game_flags.moving_forward = 0;
|
||||
flags_set ("moving_forward", false);
|
||||
break;
|
||||
case SDLK_A:
|
||||
game_flags.moving_left = 0;
|
||||
flags_set ("moving_left", false);
|
||||
break;
|
||||
case SDLK_S:
|
||||
game_flags.moving_backward = 0;
|
||||
flags_set ("moving_backward", false);
|
||||
break;
|
||||
case SDLK_D:
|
||||
game_flags.moving_right = 0;
|
||||
flags_set ("moving_right", false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+20
-1
@@ -1,3 +1,22 @@
|
||||
#include "flags.h"
|
||||
|
||||
GameFlags game_flags = { 0 };
|
||||
static GHashTable *flags;
|
||||
|
||||
void
|
||||
flags_init ()
|
||||
{
|
||||
flags = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
flags_set ("wireframe_enabled", false);
|
||||
}
|
||||
|
||||
void
|
||||
flags_set (char *flag, bool value)
|
||||
{
|
||||
g_hash_table_replace (flags, flag, GINT_TO_POINTER (value));
|
||||
}
|
||||
|
||||
bool
|
||||
flags_get (char *flag)
|
||||
{
|
||||
return GPOINTER_TO_INT (g_hash_table_lookup (flags, flag));
|
||||
}
|
||||
|
||||
+5
-14
@@ -1,18 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct GameFlags
|
||||
{
|
||||
/* Volatile state flags, zeroed at start. */
|
||||
int in_main_menu: 1;
|
||||
int in_pause_menu: 1;
|
||||
int in_game: 1;
|
||||
#include <stdbool.h>
|
||||
|
||||
int can_free_look: 1;
|
||||
int moving_forward: 1;
|
||||
int moving_backward: 1;
|
||||
int moving_left: 1;
|
||||
int moving_right: 1;
|
||||
#include <glib-2.0/glib.h>
|
||||
|
||||
int wireframe_enabled: 1;
|
||||
/* Saved state flags, loaded from game save/map. */
|
||||
} GameFlags;
|
||||
void flags_init ();
|
||||
void flags_set (char *flag, bool value);
|
||||
bool flags_get (char *flag);
|
||||
|
||||
+34
-35
@@ -1,22 +1,21 @@
|
||||
#include "graphics.h"
|
||||
|
||||
GraphicsContext gfx;
|
||||
extern vec3 camera_position;
|
||||
|
||||
extern ChunkManager chunk_manager;
|
||||
extern GameState game_state;
|
||||
extern Resources resources;
|
||||
static SDL_Window *sdl_window;
|
||||
static SDL_GLContext gl_context;
|
||||
|
||||
void
|
||||
GraphicsContext_init ()
|
||||
graphics_init ()
|
||||
{
|
||||
if (!SDL_Init (SDL_INIT_VIDEO))
|
||||
{
|
||||
FATAL ("Couldn't initialize SDL: %s", SDL_GetError ());
|
||||
}
|
||||
|
||||
gfx.window = SDL_CreateWindow (GAME_NAME, 640, 480, SDL_WINDOW_OPENGL);
|
||||
sdl_window = SDL_CreateWindow (GAME_NAME, 640, 480, SDL_WINDOW_OPENGL);
|
||||
|
||||
if (!gfx.window)
|
||||
if (!sdl_window)
|
||||
{
|
||||
FATAL ("Couldn't create window: %s", SDL_GetError ());
|
||||
}
|
||||
@@ -27,66 +26,66 @@ GraphicsContext_init ()
|
||||
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
|
||||
gfx.gl_context = SDL_GL_CreateContext (gfx.window);
|
||||
gl_context = SDL_GL_CreateContext (sdl_window);
|
||||
|
||||
if (!gfx.gl_context)
|
||||
if (!gl_context)
|
||||
{
|
||||
FATAL ("Couldn't create OpenGL context: %s", SDL_GetError ());
|
||||
}
|
||||
|
||||
SDL_GL_MakeCurrent (gfx.window, gfx.gl_context);
|
||||
SDL_SetWindowRelativeMouseMode (gfx.window, true);
|
||||
SDL_GL_MakeCurrent (sdl_window, gl_context);
|
||||
SDL_SetWindowRelativeMouseMode (sdl_window, true);
|
||||
|
||||
INFO ("Renderer: %s", glGetString (GL_RENDERER));
|
||||
INFO ("OpenGL version: %s", glGetString (GL_VERSION));
|
||||
INFO ("GLSL version: %s", glGetString (GL_SHADING_LANGUAGE_VERSION));
|
||||
INFO ("Max vertex attributes: %d", GL_MAX_VERTEX_ATTRIBS);
|
||||
|
||||
glViewport(0, 0, 640, 480);
|
||||
glViewport (0, 0, 640, 480);
|
||||
glClearColor (0, 0.3, 0.8, 1);
|
||||
|
||||
glEnable (GL_CULL_FACE);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void
|
||||
GraphicsContext_render ()
|
||||
graphics_render ()
|
||||
{
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
mat4 projection, view;
|
||||
Camera_get_projection (&game_state.camera, 640.0 / 480.0, projection);
|
||||
Camera_get_view (&game_state.camera, view);
|
||||
camera_get_projection (640.0 / 480.0, projection);
|
||||
camera_get_view (view);
|
||||
|
||||
/* Set views and projections in all programs. TODO: make this dynamic*/
|
||||
program_use (R_PRGGET ("default"));
|
||||
program_set_mat4 (R_PRGGET ("default"), "projection", projection);
|
||||
program_set_mat4 (R_PRGGET ("default"), "view", view);
|
||||
|
||||
program_use (R_PRGGET ("chunk"));
|
||||
program_set_mat4 (R_PRGGET ("chunk"), "projection", projection);
|
||||
program_set_mat4 (R_PRGGET ("chunk"), "view", view);
|
||||
program_use (RESPRG ("chunk"));
|
||||
program_set_mat4 (RESPRG ("chunk"), "projection", projection);
|
||||
program_set_mat4 (RESPRG ("chunk"), "view", view);
|
||||
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, R_TEXGET ("terrain0"));
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain0"));
|
||||
glActiveTexture (GL_TEXTURE1);
|
||||
glBindTexture (GL_TEXTURE_2D, R_TEXGET ("terrain1"));
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain1"));
|
||||
glActiveTexture (GL_TEXTURE2);
|
||||
glBindTexture (GL_TEXTURE_2D, R_TEXGET ("terrain2"));
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain2"));
|
||||
glActiveTexture (GL_TEXTURE3);
|
||||
glBindTexture (GL_TEXTURE_2D, R_TEXGET ("terrain3"));
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain3"));
|
||||
glActiveTexture (GL_TEXTURE4);
|
||||
glBindTexture (GL_TEXTURE_2D, R_TEXGET ("terrain4"));
|
||||
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain4"));
|
||||
|
||||
ChunkManager_render (game_state.camera.position, R_PRGGET ("chunk"));
|
||||
EntityManager_render (view);
|
||||
cm_render (camera_position, RESPRG ("chunk"));
|
||||
|
||||
SDL_GL_SwapWindow (gfx.window);
|
||||
/* Set views and projections in all programs. TODO: make this dynamic*/
|
||||
program_use (RESPRG ("default"));
|
||||
program_set_mat4 (RESPRG ("default"), "projection", projection);
|
||||
program_set_mat4 (RESPRG ("default"), "view", view);
|
||||
em_render (view);
|
||||
|
||||
SDL_GL_SwapWindow (sdl_window);
|
||||
}
|
||||
|
||||
void
|
||||
GraphicsContext_free ()
|
||||
graphics_free ()
|
||||
{
|
||||
SDL_GL_DestroyContext (gfx.gl_context);
|
||||
SDL_DestroyWindow (gfx.window);
|
||||
SDL_GL_DestroyContext (gl_context);
|
||||
SDL_DestroyWindow (sdl_window);
|
||||
}
|
||||
|
||||
+4
-10
@@ -7,14 +7,8 @@
|
||||
#include "chunk/manager.h"
|
||||
#include "entity/manager.h"
|
||||
#include "state.h"
|
||||
#include "resources.h"
|
||||
#include "res.h"
|
||||
|
||||
typedef struct GraphicsContext
|
||||
{
|
||||
SDL_Window *window;
|
||||
SDL_GLContext gl_context;
|
||||
} GraphicsContext;
|
||||
|
||||
void GraphicsContext_init ();
|
||||
void GraphicsContext_render ();
|
||||
void GraphicsContext_free ();
|
||||
void graphics_init ();
|
||||
void graphics_render ();
|
||||
void graphics_free ();
|
||||
|
||||
+14
-17
@@ -8,11 +8,10 @@
|
||||
#include "chunk/manager.h"
|
||||
#include "entity/templates.h"
|
||||
#include "state.h"
|
||||
#include "resources.h"
|
||||
#include "res.h"
|
||||
#include "graphics.h"
|
||||
|
||||
extern GameState game_state;
|
||||
extern GameFlags game_flags;
|
||||
extern vec3 camera_position;
|
||||
|
||||
SDL_AppResult
|
||||
SDL_AppInit (void **appstate, int argc, char **argv)
|
||||
@@ -20,16 +19,14 @@ SDL_AppInit (void **appstate, int argc, char **argv)
|
||||
UNUSED (appstate, argc, argv);
|
||||
SDL_SetAppMetadata (GAME_NAME, GAME_VERSION, "eur.chopininteractive.wschod-game");
|
||||
|
||||
GraphicsContext_init ();
|
||||
graphics_init ();
|
||||
handlers_init ();
|
||||
Resources_init ();
|
||||
ChunkManager_init ();
|
||||
EntityManager_init ();
|
||||
EntityTemplates_init ();
|
||||
GameState_init (SDL_GetTicks ());
|
||||
/* Set some basic game flags for testing. */
|
||||
game_flags.can_free_look = 1;
|
||||
game_flags.wireframe_enabled = 0;
|
||||
res_init ();
|
||||
cm_init ();
|
||||
em_init ();
|
||||
ent_templates_init ();
|
||||
flags_init ();
|
||||
game_state_init (SDL_GetTicks ());
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
@@ -53,10 +50,10 @@ SDL_AppIterate (void *appstate)
|
||||
{
|
||||
UNUSED (appstate);
|
||||
|
||||
GameState_tick (SDL_GetTicks ());
|
||||
EntityManager_tick ();
|
||||
ChunkManager_update (game_state.camera.position);
|
||||
GraphicsContext_render ();
|
||||
game_state_tick (SDL_GetTicks ());
|
||||
em_tick ();
|
||||
cm_update (camera_position);
|
||||
graphics_render ();
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
@@ -65,5 +62,5 @@ void
|
||||
SDL_AppQuit (void *appstate, SDL_AppResult result)
|
||||
{
|
||||
UNUSED (appstate, result);
|
||||
GraphicsContext_free ();
|
||||
graphics_free ();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "res.h"
|
||||
|
||||
static GHashTable *programs;
|
||||
static GHashTable *textures;
|
||||
|
||||
unsigned int
|
||||
res_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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
res_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 ());
|
||||
}
|
||||
|
||||
unsigned int texture = texture_create (surface->w, surface->h, surface->pixels);
|
||||
return texture;
|
||||
}
|
||||
|
||||
static inline void
|
||||
res_add_program (char *key, unsigned int program)
|
||||
{
|
||||
g_hash_table_insert (programs, key, GINT_TO_POINTER (program));
|
||||
}
|
||||
|
||||
static inline void
|
||||
res_add_texture (char *key, unsigned int texture)
|
||||
{
|
||||
g_hash_table_insert (textures, key, GINT_TO_POINTER (texture));
|
||||
}
|
||||
|
||||
unsigned int
|
||||
res_get_program (char *key)
|
||||
{
|
||||
return GPOINTER_TO_INT (g_hash_table_lookup (programs, key));
|
||||
}
|
||||
|
||||
unsigned int
|
||||
res_get_texture (char *key)
|
||||
{
|
||||
return GPOINTER_TO_INT (g_hash_table_lookup (textures, key));
|
||||
}
|
||||
|
||||
void
|
||||
res_init ()
|
||||
{
|
||||
programs = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
textures = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
res_add_program ("default", res_load_program ("res/shaders/default.vert", "res/shaders/default.frag"));
|
||||
res_add_program ("chunk", res_load_program ("res/shaders/chunk.vert", "res/shaders/chunk.frag"));
|
||||
|
||||
program_use (res_get_program ("chunk"));
|
||||
program_set_int_array (res_get_program ("chunk"), "materials", 5, (int[5]) { 0, 1, 2, 3, 4 });
|
||||
|
||||
res_add_texture ("terrain0", res_load_texture ("res/textures/dirt.png"));
|
||||
res_add_texture ("terrain1", res_load_texture ("res/textures/drygrass.png"));
|
||||
res_add_texture ("terrain2", res_load_texture ("res/textures/grass.png"));
|
||||
res_add_texture ("terrain3", res_load_texture ("res/textures/rock_cement.png"));
|
||||
res_add_texture ("terrain4", res_load_texture ("res/textures/asphalt_gravel.png"));
|
||||
|
||||
res_add_texture ("tree0", res_load_texture ("res/textures/tree.png"));
|
||||
res_add_texture ("grass0", res_load_texture ("res/textures/grass0.png"));
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
#include <glib-2.0/glib.h>
|
||||
|
||||
#include "program.h"
|
||||
#include "texture.h"
|
||||
|
||||
#define RESPRG(key) (res_get_program (key))
|
||||
#define RESTEX(key) (res_get_texture (key))
|
||||
|
||||
unsigned int res_get_program (char *key);
|
||||
unsigned int res_get_texture (char *key);
|
||||
void res_init ();
|
||||
@@ -1,74 +0,0 @@
|
||||
#include "resources.h"
|
||||
|
||||
Resources resources;
|
||||
|
||||
void
|
||||
Resources_init ()
|
||||
{
|
||||
resources.programs = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
resources.textures = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
R_PRGADD ("default", R_PRGLOAD ("res/shaders/default.vert", "res/shaders/default.frag"));
|
||||
R_PRGADD ("chunk", R_PRGLOAD ("res/shaders/chunk.vert", "res/shaders/chunk.frag"));
|
||||
|
||||
program_use (R_PRGGET ("chunk"));
|
||||
program_set_int_array (R_PRGGET ("chunk"), "materials", 5, (int[5]) { 0, 1, 2, 3, 4 });
|
||||
|
||||
R_TEXADD ("terrain0", R_TEXLOAD ("res/textures/dirt.png"));
|
||||
R_TEXADD ("terrain1", R_TEXLOAD ("res/textures/drygrass.png"));
|
||||
R_TEXADD ("terrain2", R_TEXLOAD ("res/textures/grass.png"));
|
||||
R_TEXADD ("terrain3", R_TEXLOAD ("res/textures/rock_cement.png"));
|
||||
R_TEXADD ("terrain4", R_TEXLOAD ("res/textures/asphalt_gravel.png"));
|
||||
|
||||
R_TEXADD ("tree0", R_TEXLOAD ("res/textures/tree.png"));
|
||||
R_TEXADD ("grass0", R_TEXLOAD ("res/textures/grass0.png"));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 ());
|
||||
}
|
||||
|
||||
unsigned int texture = texture_create (surface->w, surface->h, surface->pixels);
|
||||
return texture;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
#include <glib-2.0/glib.h>
|
||||
|
||||
#include "program.h"
|
||||
#include "texture.h"
|
||||
|
||||
#define R_PRGADD(key, program) (g_hash_table_insert (resources.programs, key, GINT_TO_POINTER (program)))
|
||||
#define R_TEXADD(key, texture) (g_hash_table_insert (resources.textures, key, GINT_TO_POINTER (texture)))
|
||||
#define R_PRGLOAD(v_path, f_path) (Resources_load_program (v_path, f_path))
|
||||
#define R_TEXLOAD(path) (Resources_load_texture (path))
|
||||
#define R_PRGGET(key) (GPOINTER_TO_INT (g_hash_table_lookup (resources.programs, key)))
|
||||
#define R_TEXGET(key) (GPOINTER_TO_INT (g_hash_table_lookup (resources.textures, key)))
|
||||
|
||||
typedef struct Resources {
|
||||
GHashTable *programs;
|
||||
GHashTable *textures;
|
||||
} Resources;
|
||||
|
||||
unsigned int Resources_load_program (const char *v_path, const char *f_path);
|
||||
unsigned int Resources_load_texture (const char *path);
|
||||
|
||||
void Resources_init ();
|
||||
+28
-29
@@ -1,57 +1,56 @@
|
||||
#include "state.h"
|
||||
|
||||
GameState game_state;
|
||||
extern vec3 camera_position;
|
||||
|
||||
extern GameFlags game_flags;
|
||||
float delta_time;
|
||||
static int last_time;
|
||||
|
||||
void
|
||||
GameState_init (int ticks)
|
||||
game_state_init (int ticks)
|
||||
{
|
||||
game_state.last_time = ticks;
|
||||
game_state.camera = Camera_default ();
|
||||
game_state.camera.position[2] = -1.0;
|
||||
last_time = ticks;
|
||||
}
|
||||
|
||||
void
|
||||
GameState_tick (int ticks)
|
||||
game_state_tick (int ticks)
|
||||
{
|
||||
/* Caluclate stuff per frame. */
|
||||
game_state.delta_time = (ticks - game_state.last_time) / 1000.0;
|
||||
game_state.last_time = ticks;
|
||||
delta_time = (ticks - last_time) / 1000.0;
|
||||
last_time = ticks;
|
||||
|
||||
if (game_flags.moving_forward)
|
||||
if (flags_get ("moving_forward"))
|
||||
{
|
||||
vec3 dir, change, new_pos;
|
||||
Camera_get_direction (&game_state.camera, dir);
|
||||
glm_vec3_scale (dir, game_state.delta_time * 5, change);
|
||||
glm_vec3_add (game_state.camera.position, change, new_pos);
|
||||
glm_vec3_copy (new_pos, game_state.camera.position);
|
||||
camera_get_direction (dir);
|
||||
glm_vec3_scale (dir, delta_time * 5, change);
|
||||
glm_vec3_add (camera_position, change, new_pos);
|
||||
glm_vec3_copy (new_pos, camera_position);
|
||||
}
|
||||
|
||||
if (game_flags.moving_backward)
|
||||
if (flags_get ("moving_backward"))
|
||||
{
|
||||
vec3 dir, change, new_pos;
|
||||
Camera_get_direction (&game_state.camera, dir);
|
||||
glm_vec3_scale (dir, game_state.delta_time * 5, change);
|
||||
glm_vec3_sub (game_state.camera.position, change, new_pos);
|
||||
glm_vec3_copy (new_pos, game_state.camera.position);
|
||||
camera_get_direction (dir);
|
||||
glm_vec3_scale (dir, delta_time * 5, change);
|
||||
glm_vec3_sub (camera_position, change, new_pos);
|
||||
glm_vec3_copy (new_pos, camera_position);
|
||||
}
|
||||
|
||||
if (game_flags.moving_right)
|
||||
if (flags_get ("moving_right"))
|
||||
{
|
||||
vec3 right, change, new_pos;
|
||||
Camera_get_right (&game_state.camera, right);
|
||||
glm_vec3_scale (right, game_state.delta_time * 5, change);
|
||||
glm_vec3_add (game_state.camera.position, change, new_pos);
|
||||
glm_vec3_copy (new_pos, game_state.camera.position);
|
||||
camera_get_right (right);
|
||||
glm_vec3_scale (right, delta_time * 5, change);
|
||||
glm_vec3_add (camera_position, change, new_pos);
|
||||
glm_vec3_copy (new_pos, camera_position);
|
||||
}
|
||||
|
||||
if (game_flags.moving_left)
|
||||
if (flags_get ("moving_left"))
|
||||
{
|
||||
vec3 right, change, new_pos;
|
||||
Camera_get_right (&game_state.camera, right);
|
||||
glm_vec3_scale (right, game_state.delta_time * 5, change);
|
||||
glm_vec3_sub (game_state.camera.position, change, new_pos);
|
||||
glm_vec3_copy (new_pos, game_state.camera.position);
|
||||
camera_get_right (right);
|
||||
glm_vec3_scale (right, delta_time * 5, change);
|
||||
glm_vec3_sub (camera_position, change, new_pos);
|
||||
glm_vec3_copy (new_pos, camera_position);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-10
@@ -3,13 +3,5 @@
|
||||
#include "camera.h"
|
||||
#include "flags.h"
|
||||
|
||||
typedef struct GameState
|
||||
{
|
||||
int last_time;
|
||||
float delta_time;
|
||||
|
||||
Camera camera;
|
||||
} GameState;
|
||||
|
||||
void GameState_init ();
|
||||
void GameState_tick ();
|
||||
void game_state_init (int ticks);
|
||||
void game_state_tick (int ticks);
|
||||
|
||||
Reference in New Issue
Block a user