diff --git a/game/Makefile b/game/Makefile index 5ac32d7..73da4b9 100644 --- a/game/Makefile +++ b/game/Makefile @@ -1,9 +1,9 @@ -SRC=src/math_3d.c src/main.c src/mesh.c src/program.c src/resources.c src/camera.c \ - src/chunk/chunk.c src/chunk/noise.c src/chunk/chunkmesh.c src/flags.c src/texture.c +SRC=src/math_3d.c src/main.c src/program.c src/resources.c src/camera.c \ + src/chunk/chunk.c src/chunk/mesh.c src/flags.c src/texture.c src/chunk/manager.c OBJ=$(SRC:.c=.o) -CFLAGS=-Werror -Wextra -Wall `pkg-config --cflags sdl3 sdl3-image gl` -LDFLAGS=`pkg-config --libs sdl3 sdl3-image gl` -lm +CFLAGS=-Werror -Wextra -Wall `pkg-config --cflags sdl3 sdl3-image gl glib-2.0` +LDFLAGS=`pkg-config --libs sdl3 sdl3-image gl glib-2.0` -lm TARGET=wschod CC=gcc LD=gcc diff --git a/game/res/shaders/chunk.frag b/game/res/shaders/chunk.frag index 0c7b037..b57d3cd 100644 --- a/game/res/shaders/chunk.frag +++ b/game/res/shaders/chunk.frag @@ -3,19 +3,18 @@ precision lowp float; varying vec2 f_uv; -varying vec3 f_material; +varying vec4 f_material; varying float f_height; uniform sampler2D materials[5]; void main () { - /* This means there can be four textures on a terrain. Could be - extended, but who cares? */ vec4 result = texture2D (materials[0], f_uv); result = mix (result, texture2D (materials[1], f_uv), f_material[0]); result = mix (result, texture2D (materials[2], f_uv), f_material[1]); result = mix (result, texture2D (materials[3], f_uv), f_material[2]); + result = mix (result, texture2D (materials[4], f_uv), f_material[3]); gl_FragColor = result; } diff --git a/game/res/shaders/chunk.vert b/game/res/shaders/chunk.vert index d75c126..1e40989 100644 --- a/game/res/shaders/chunk.vert +++ b/game/res/shaders/chunk.vert @@ -1,14 +1,15 @@ #version 100 attribute vec4 position; -attribute vec3 material; +attribute vec4 material; + +varying vec2 f_uv; +varying vec4 f_material; +varying float f_height; uniform mat4 view; uniform mat4 projection; - -varying vec2 f_uv; -varying vec3 f_material; -varying float f_height; +uniform vec4 chunk_position; void main () { @@ -16,5 +17,5 @@ void main () f_material = material; f_height = position.y; - gl_Position = projection * view * position; + gl_Position = projection * view * (position + chunk_position); } diff --git a/game/res/textures/asphalt_gravel.png b/game/res/textures/asphalt_gravel.png index 930b6b0..14a8497 100644 Binary files a/game/res/textures/asphalt_gravel.png and b/game/res/textures/asphalt_gravel.png differ diff --git a/game/res/textures/dirt.png b/game/res/textures/dirt.png index 2be0e39..992753a 100644 Binary files a/game/res/textures/dirt.png and b/game/res/textures/dirt.png differ diff --git a/game/res/textures/drygrass.png b/game/res/textures/drygrass.png index d12625d..fd2861f 100644 Binary files a/game/res/textures/drygrass.png and b/game/res/textures/drygrass.png differ diff --git a/game/res/textures/grass.png b/game/res/textures/grass.png index 1f0c342..0e2423b 100644 Binary files a/game/res/textures/grass.png and b/game/res/textures/grass.png differ diff --git a/game/res/textures/rock_cement.png b/game/res/textures/rock_cement.png index a49d952..f4947f5 100644 Binary files a/game/res/textures/rock_cement.png and b/game/res/textures/rock_cement.png differ diff --git a/game/shell.nix b/game/shell.nix index ea8db3a..cb16345 100644 --- a/game/shell.nix +++ b/game/shell.nix @@ -6,13 +6,15 @@ in pkgs.mkShellNoCC { packages = with pkgs; [ - gcc - pkg-config sdl3 sdl3-image - gdb cglm glew + glib + + gcc + pkg-config valgrind + gdb ]; } diff --git a/game/src/camera.c b/game/src/camera.c index b0200ce..6ccb387 100644 --- a/game/src/camera.c +++ b/game/src/camera.c @@ -46,3 +46,9 @@ Camera_get_projection (Camera *camera, float aspect) return m4_perspective (camera->fov, aspect, camera->near, camera->far); } + +void +Camera_print (Camera *camera) +{ + INFO ("Camera position: (%6.1f, %6.1f, %6.1f)", camera->position.x, camera->position.y, camera->position.z); +} diff --git a/game/src/camera.h b/game/src/camera.h index 5e8ef89..a70a035 100644 --- a/game/src/camera.h +++ b/game/src/camera.h @@ -18,3 +18,4 @@ vec3_t Camera_get_direction (Camera *camera); vec3_t Camera_get_right (Camera *camera); mat4_t Camera_get_view (Camera *camera); mat4_t Camera_get_projection (Camera *camera, float aspect); +void Camera_print (Camera *camera); diff --git a/game/src/chunk/chunk.c b/game/src/chunk/chunk.c index 6147786..845f8f9 100644 --- a/game/src/chunk/chunk.c +++ b/game/src/chunk/chunk.c @@ -2,29 +2,24 @@ #include -Chunk +Chunk * Chunk_new () { - Chunk chunk; - chunk.heightmap = malloc (sizeof (float) * CHUNK_SIZE); - chunk.materialmap = malloc (sizeof (char) * CHUNK_SIZE); - INFO ("Created new Chunk. Memory size: %zu bytes", - sizeof (float) * CHUNK_SIZE + sizeof (char) * CHUNK_SIZE); + Chunk *chunk = malloc (sizeof (Chunk)); + chunk->heightmap = malloc (sizeof (float) * CHUNK_SIZE); + chunk->materialmap = malloc (sizeof (char) * CHUNK_SIZE); return chunk; } void -Chunk_noise (Chunk *chunk, int xoffset, int yoffset) +Chunk_random (Chunk *chunk) { for (int y = 0; y < CHUNK_DIM; ++y) { for (int x = 0; x < CHUNK_DIM; ++x) { - (void) xoffset; (void) yoffset; - float val = sinf (x) + sinf (y); - (void) val; chunk->heightmap[INDEX (x, y)] = 0; - chunk->materialmap[INDEX (x, y)] = rand () % 2; + chunk->materialmap[INDEX (x, y)] = rand () % 5; } } } diff --git a/game/src/chunk/chunk.h b/game/src/chunk/chunk.h index bea42f6..e4b03af 100644 --- a/game/src/chunk/chunk.h +++ b/game/src/chunk/chunk.h @@ -1,7 +1,8 @@ #pragma once +#include + #include "../util.h" -#include "noise.h" #define CHUNK_DIM 16 #define CHUNK_SIZE (CHUNK_DIM*CHUNK_DIM) @@ -14,7 +15,7 @@ typedef struct Chunk char *materialmap; } Chunk; -Chunk Chunk_new (); -void Chunk_noise (Chunk *chunk, int xoffset, int yoffset); +Chunk *Chunk_new (); +void Chunk_random (Chunk *chunk); void Chunk_free (Chunk *chunk); void Chunk_heightmap_print (Chunk *chunk); diff --git a/game/src/chunk/manager.c b/game/src/chunk/manager.c new file mode 100644 index 0000000..fe0a0b2 --- /dev/null +++ b/game/src/chunk/manager.c @@ -0,0 +1,134 @@ +#include "manager.h" + +/* TODO: switch from string keys to struct keys or some other + stuff. */ + +ChunkManager chunk_manager; + +void +ChunkManager_init () +{ + chunk_manager.chunks = g_hash_table_new (g_str_hash, g_str_equal); + chunk_manager.chunk_meshes = g_hash_table_new (g_str_hash, g_str_equal); +} + +void +cm_get_chunk_pos (float x, float y, int *ox, int *oy) +{ + *ox = floor (x / (float) CHUNK_DIM); + *oy = floor (y / (float) CHUNK_DIM); +} + +char * +cm_coords_to_string (int ox, int oy) +{ + char *buffer = malloc (sizeof (char) * 128); + snprintf (buffer, 128, "%d %d", ox, oy); + return buffer; +} + +void +ChunkManager_update (float px, float py) +/* x = camera's X position, y = camera's Y position */ +{ + (void) px; (void) py; + int cx = 0, cy = 0; + + /* cm_get_chunk_pos (px, py, &cx, &cy); */ + + for (int y = cy - RENDER_DISTANCE - 1; y <= cy + RENDER_DISTANCE + 1; ++y) + { + for (int x = cx - RENDER_DISTANCE - 1; x <= cx + RENDER_DISTANCE + 1; ++x) + { + if (ChunkManager_get_chunk_at (x, y) == NULL) + { + ChunkManager_generate_chunk_at (x, y); + } + } + } + + for (int y = cy - RENDER_DISTANCE; y <= cy + RENDER_DISTANCE; ++y) + { + for (int x = cx - RENDER_DISTANCE; x <= cx + RENDER_DISTANCE; ++x) + { + if (ChunkManager_get_chunk_mesh_at (x, y) == NULL) + { + ChunkManager_generate_chunk_mesh_at (x, y); + } + } + } +} + +void +ChunkManager_render (float px, float py, int program) +{ + (void) px; (void) py; + int cx = 0, cy = 0; + /* cm_get_chunk_pos (px, py, &cx, &cy); */ + + for (int y = cy - RENDER_DISTANCE; y <= cy + RENDER_DISTANCE; ++y) + { + for (int x = cx - RENDER_DISTANCE; x <= cx + RENDER_DISTANCE; ++x) + { + ChunkMesh *mesh = ChunkManager_get_chunk_mesh_at (x, y); + if (mesh != NULL) + { + program_set_vec4 (program, "chunk_position", x * CHUNKMESH_DIM, 0.0, y * CHUNKMESH_DIM, 1.0); + ChunkMesh_render (mesh); + } + } + } +} + +Chunk * +ChunkManager_get_chunk_at (int x, int y) +{ + char *key = cm_coords_to_string (x, y); + return (Chunk *) g_hash_table_lookup (chunk_manager.chunks, key); +} + +void +ChunkManager_set_chunk_at (int x, int y, Chunk *chunk) +{ + char *key = cm_coords_to_string (x, y); + g_hash_table_insert (chunk_manager.chunks, key, chunk); +} + +void +ChunkManager_generate_chunk_at (int x, int y) +{ + Chunk *chunk = Chunk_new (); + Chunk_random (chunk); + ChunkManager_set_chunk_at (x, y, chunk); +} + +void +ChunkManager_get_chunk_neighbors_at (int x, int y, Chunk **nr, Chunk **nd, Chunk **nc) +{ + *nr = ChunkManager_get_chunk_at (x + 1, y); + *nd = ChunkManager_get_chunk_at (x, y + 1); + *nc = ChunkManager_get_chunk_at (x + 1, y + 1); +} + +ChunkMesh * +ChunkManager_get_chunk_mesh_at (int x, int y) +{ + char *key = cm_coords_to_string (x, y); + return (ChunkMesh *) g_hash_table_lookup (chunk_manager.chunk_meshes, key); +} + +void +ChunkManager_set_chunk_mesh_at (int x, int y, ChunkMesh *mesh) +{ + char *key = cm_coords_to_string (x, y); + g_hash_table_insert (chunk_manager.chunk_meshes, key, mesh); +} + +void +ChunkManager_generate_chunk_mesh_at (int x, int y) +{ + Chunk *nr, *nd, *nc; + ChunkManager_get_chunk_neighbors_at (x, y, &nr, &nd, &nc); + ChunkManager_set_chunk_mesh_at + (x, y, ChunkMesh_from_Chunk_and_neighbors (ChunkManager_get_chunk_at (x, y), nr, nd, nc)); +} diff --git a/game/src/chunk/manager.h b/game/src/chunk/manager.h new file mode 100644 index 0000000..eb4de2d --- /dev/null +++ b/game/src/chunk/manager.h @@ -0,0 +1,33 @@ +#pragma once + +/* Yes, glib. */ +#include + +#include "../program.h" +#include "chunk.h" +#include "mesh.h" + +#define RENDER_DISTANCE 1 + +typedef struct ChunkManager +{ + GHashTable *chunks; + GHashTable *chunk_meshes; + + GAsyncQueue *chunk_queue; + GAsyncQueue *chunk_mesh_queue; +} ChunkManager; + +void ChunkManager_init (); +void ChunkManager_update (float px, float py); +void ChunkManager_render (float px, float py, int program); + +Chunk *ChunkManager_get_chunk_at (int x, int y); +void ChunkManager_get_chunk_neighbors_at (int x, int y, Chunk **nr, Chunk **nd, Chunk **nc); +void ChunkManager_set_chunk_at (int x, int y, Chunk *chunk); + +ChunkMesh *ChunkManager_get_chunk_mesh_at (int x, int y); +void ChunkManager_set_chunk_mesh_at (int x, int y, ChunkMesh *mesh); + +void ChunkManager_generate_chunk_at (int x, int y); +void ChunkManager_generate_chunk_mesh_at (int x, int y); diff --git a/game/src/chunk/chunkmesh.c b/game/src/chunk/mesh.c similarity index 56% rename from game/src/chunk/chunkmesh.c rename to game/src/chunk/mesh.c index 29a1cd7..43b3635 100644 --- a/game/src/chunk/chunkmesh.c +++ b/game/src/chunk/mesh.c @@ -1,20 +1,16 @@ -#include "chunkmesh.h" +#include "mesh.h" extern GameFlags game_flags; -ChunkMesh -ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *nc) +ChunkMesh * +ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nr, Chunk *nd, Chunk *nc) /* nd --- down neighbor; nr --- right neighbor; nc --- corner neighbor */ { vec3_t *positions = malloc (sizeof (vec3_t) * CHUNKMESH_SIZE); - vec3_t *materials = malloc (sizeof (vec3_t) * CHUNKMESH_SIZE); + float *materials = malloc (sizeof (float) * 4 * CHUNKMESH_SIZE); unsigned int *indices = malloc (sizeof (unsigned int) * CHUNKMESH_SIZE * 6); - INFO ("Temporarily allocated %zu bytes for ChunkMesh.", - (sizeof (vec3_t) * CHUNKMESH_SIZE * 2 - + sizeof (unsigned int) * CHUNKMESH_SIZE * 6)); - - int i_i = 0; + int m_i = 0, i_i = 0; for (int y = 0; y < CHUNKMESH_DIM; ++y) { for (int x = 0; x < CHUNKMESH_DIM; ++x) @@ -22,28 +18,29 @@ ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *n float height = chunk->heightmap[INDEX (x, y)]; float material_id = chunk->materialmap[INDEX (x, y)]; - if (x == CHUNK_DIM && y < CHUNKMESH_DIM && nr != NULL) + if (x == CHUNK_DIM && y < CHUNK_DIM && nr != NULL) { height = nr->heightmap[INDEX (0, y)]; material_id = nr->materialmap[INDEX (0, y)]; } - if (y == CHUNK_DIM && x < CHUNKMESH_DIM && nd != NULL) + if (y == CHUNK_DIM && x < CHUNK_DIM && nd != NULL) { height = nd->heightmap[INDEX (x, 0)]; - material_id = nr->materialmap[INDEX (x, 0)]; + material_id = nd->materialmap[INDEX (x, 0)]; } if (x == CHUNK_DIM && y == CHUNK_DIM && nc != NULL) { height = nc->heightmap[INDEX (0, 0)]; - material_id = nr->materialmap[INDEX (0, 0)]; + material_id = nc->materialmap[INDEX (0, 0)]; } positions[CMINDEX (x, y)] = vec3 (x, height, y); - materials[CMINDEX (x, y)] = vec3 - (material_id == 1 ? 1 : 0, material_id == 2 ? 1 : 0, - material_id == 3 ? 1 : 0); + materials[m_i++] = material_id == 1 ? 1 : 0; + materials[m_i++] = material_id == 2 ? 1 : 0; + materials[m_i++] = material_id == 3 ? 1 : 0; + materials[m_i++] = material_id == 4 ? 1 : 0; if (x < CHUNK_DIM && y < CHUNK_DIM) { @@ -69,22 +66,22 @@ ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *n } } - ChunkMesh mesh; - glGenBuffers (1, &mesh.pbo); - glGenBuffers (1, &mesh.mbo); - glGenBuffers (1, &mesh.ebo); + ChunkMesh *mesh = malloc (sizeof (ChunkMesh)); + glGenBuffers (1, &mesh->pbo); + glGenBuffers (1, &mesh->mbo); + glGenBuffers (1, &mesh->ebo); - glBindBuffer (GL_ARRAY_BUFFER, mesh.pbo); + glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo); glBufferData (GL_ARRAY_BUFFER, sizeof (vec3_t) * CHUNKMESH_SIZE, positions, GL_STATIC_DRAW); glEnableVertexAttribArray (0); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (vec3_t), 0); - glBindBuffer (GL_ARRAY_BUFFER, mesh.mbo); - glBufferData (GL_ARRAY_BUFFER, sizeof (vec3_t) * CHUNKMESH_SIZE, materials, GL_STATIC_DRAW); + glBindBuffer (GL_ARRAY_BUFFER, mesh->mbo); + glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 4 * CHUNKMESH_SIZE, materials, GL_STATIC_DRAW); glEnableVertexAttribArray (1); - glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, sizeof (vec3_t), 0); + glVertexAttribPointer (1, 4, GL_FLOAT, GL_FALSE, sizeof (float) * 4, 0); - glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh.ebo); + glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->ebo); glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (unsigned int) * CHUNKMESH_SIZE * 6, indices, GL_STATIC_DRAW); glBindBuffer (GL_ARRAY_BUFFER, 0); @@ -100,15 +97,23 @@ ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *n void ChunkMesh_render (ChunkMesh *mesh) { + glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo); + glEnableVertexAttribArray (0); + glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (vec3_t), 0); + + glBindBuffer (GL_ARRAY_BUFFER, mesh->mbo); + glEnableVertexAttribArray (1); + glVertexAttribPointer (1, 4, GL_FLOAT, GL_FALSE, sizeof (float) * 4, 0); + glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->ebo); if (game_flags.wireframe_enabled) { - glDrawElements (GL_LINES, CHUNKMESH_SIZE * 6, GL_UNSIGNED_INT, 0); + glDrawElements (GL_LINES, CHUNK_SIZE * 6, GL_UNSIGNED_INT, 0); } else { - glDrawElements (GL_TRIANGLES, CHUNKMESH_SIZE * 6, GL_UNSIGNED_INT, 0); + glDrawElements (GL_TRIANGLES, CHUNK_SIZE * 6, GL_UNSIGNED_INT, 0); } glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0); diff --git a/game/src/chunk/chunkmesh.h b/game/src/chunk/mesh.h similarity index 75% rename from game/src/chunk/chunkmesh.h rename to game/src/chunk/mesh.h index abee039..a3ae743 100644 --- a/game/src/chunk/chunkmesh.h +++ b/game/src/chunk/mesh.h @@ -6,7 +6,6 @@ #include "../math_3d.h" #include "chunk.h" -/* TODO: set to + 1 */ #define CHUNKMESH_DIM (CHUNK_DIM+1) #define CHUNKMESH_SIZE (CHUNKMESH_DIM*CHUNKMESH_DIM) #define CMINDEX(x, y) (CHUNKMESH_DIM * (y) + (x)) @@ -18,5 +17,6 @@ typedef struct ChunkMesh unsigned int ebo; } ChunkMesh; -ChunkMesh ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *nc); +/* Rename to ChunkMesh_build */ +ChunkMesh *ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nr, Chunk *nd, Chunk *nc); void ChunkMesh_render (ChunkMesh *mesh); diff --git a/game/src/chunk/noise.c b/game/src/chunk/noise.c deleted file mode 100644 index ab13569..0000000 --- a/game/src/chunk/noise.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "noise.h" - -static u_int8_t *perm; - -void -noise_seed (int seed) -{ - srand (seed); - perm = malloc (sizeof (u_int8_t) * 256); - - for (size_t i = 0; i < 256; ++i) { - perm[i] = i; - } - - for (size_t i = 0; i < 255; ++i) { - size_t j = i + rand() / (RAND_MAX / (256 - i) + 1); - u_int8_t t = perm[j]; - perm[j] = perm[i]; - perm[i] = t; - } -} - -float -noise2 (float x, float y) -{ - int X = (int) FASTFLOOR (x) & 0xff; - int Y = (int) FASTFLOOR (y) & 0xff; - x -= FASTFLOOR (x); - y -= FASTFLOOR (y); - float u = FADE (x); - float v = FADE (y); - int A = (perm[X] + Y) & 0xff; - int B = (perm[X + 1] + Y) & 0xff; - - return LERP - (v, LERP - (u, GRAD2 - (perm[A], x, y), - GRAD2(perm[B], x - 1, y)), - LERP(u, GRAD2 - (perm[A + 1], x, y - 1), - GRAD2(perm[B + 1], x - 1, y - 1))); -} diff --git a/game/src/chunk/noise.h b/game/src/chunk/noise.h deleted file mode 100644 index 4f09dc1..0000000 --- a/game/src/chunk/noise.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -#define FADE(t) (((6 * t - 15) * t + 10) * t * t * t) -#define LERP(t, a, b) (a + t * (b - a)) -#define FASTFLOOR(x) (((int) (x) < (x)) ? ((int) x) : ((int) x - 1)) - -static inline float -GRAD2 (int hash, float x, float y) -{ - return ((hash & 1) ? -x : x) + ((hash & 2) ? -y : y); -} - -void noise_seed (int seed); -float noise2 (float x, float y); diff --git a/game/src/main.c b/game/src/main.c index 179c058..6cf8672 100644 --- a/game/src/main.c +++ b/game/src/main.c @@ -4,11 +4,10 @@ #include -#include "chunk/chunkmesh.h" +#include "chunk/manager.h" #include "state.h" #include "flags.h" #include "camera.h" -#include "mesh.h" #include "resources.h" /* TODO: switch back to cglm.h, since it's faster or something */ @@ -19,8 +18,8 @@ static SDL_GLContext context = NULL; extern GameState game_state; extern GameFlags game_flags; extern Resources resources; +extern ChunkManager chunk_manager; -static ChunkMesh test_chunkmesh; static Camera camera; SDL_AppResult @@ -71,16 +70,11 @@ SDL_AppInit (void **appstate, int argc, char **argv) /* Initialize and load resources. */ Resources_init (); - noise_seed (1337); - - /* Generate a test chunk. */ - Chunk chunk = Chunk_new (); - Chunk_noise (&chunk, 0, 0); - test_chunkmesh = ChunkMesh_from_Chunk_and_neighbors (&chunk, NULL, NULL, NULL); + ChunkManager_init (); program_use (resources.programs[1]); - int arr[4] = { 0, 1, 2, 3 }; - program_set_int_array (resources.programs[1], "materials", 4, arr); + int arr[5] = { 0, 1, 2, 3, 4 }; + program_set_int_array (resources.programs[1], "materials", 5, arr); /* Set up game state. */ game_state.last_time = SDL_GetTicks (); @@ -91,7 +85,6 @@ SDL_AppInit (void **appstate, int argc, char **argv) /* Initialize the default camera. */ camera = Camera_default (); - camera.position.z = -1.0; return SDL_APP_CONTINUE; } @@ -133,6 +126,14 @@ SDL_AppEvent (void *appstate, SDL_Event *event) case SDLK_F1: game_flags.wireframe_enabled = !game_flags.wireframe_enabled; break; + case SDLK_F2: + int active_program; + glGetIntegerv (GL_CURRENT_PROGRAM, &active_program); + program_print (active_program); + break; + case SDLK_F3: + Camera_print (&camera); + break; } } @@ -172,48 +173,47 @@ SDL_AppIterate (void *appstate) { camera.position = v3_add (camera.position, v3_muls - (Camera_get_direction (&camera), game_state.delta_time)); + (Camera_get_direction (&camera), game_state.delta_time * 5)); } if (game_flags.moving_backward) { camera.position = v3_sub (camera.position, v3_muls - (Camera_get_direction (&camera), game_state.delta_time)); + (Camera_get_direction (&camera), game_state.delta_time * 5)); } if (game_flags.moving_right) { camera.position = v3_add (camera.position, v3_muls - (Camera_get_right (&camera), game_state.delta_time)); + (Camera_get_right (&camera), game_state.delta_time * 5)); } if (game_flags.moving_left) { camera.position = v3_sub (camera.position, v3_muls - (Camera_get_right (&camera), game_state.delta_time)); + (Camera_get_right (&camera), game_state.delta_time * 5)); } + + ChunkManager_update (camera.position.x, camera.position.z); /* Render stuff. */ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - mat4_t view = Camera_get_view (&camera); - mat4_t projection = Camera_get_projection (&camera, 640.0 / 480.0); program_use (resources.programs[1]); + program_set_mat4 (resources.programs[1], "projection", Camera_get_projection (&camera, 640.0 / 480.0)); + program_set_mat4 (resources.programs[1], "view", Camera_get_view (&camera)); for (size_t i = 0; i < resources.textures_len; ++i) { glActiveTexture (GL_TEXTURE0 + i); glBindTexture (GL_TEXTURE_2D, resources.textures[i]); } - - program_set_mat4 (resources.programs[1], "view", view); - program_set_mat4 (resources.programs[1], "projection", projection); - ChunkMesh_render (&test_chunkmesh); + + ChunkManager_render (camera.position.x, camera.position.z, resources.programs[1]); glBindTexture (GL_TEXTURE_2D, 0); diff --git a/game/src/mesh.c b/game/src/mesh.c deleted file mode 100644 index f58e730..0000000 --- a/game/src/mesh.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "mesh.h" - -Mesh -Mesh_new (size_t vertices_len, float *vertices) -{ - Mesh mesh = { vertices_len, vertices, 0 }; - glGenBuffers (1, &mesh.vbo); - glBindBuffer (GL_ARRAY_BUFFER, mesh.vbo); - glBufferData (GL_ARRAY_BUFFER, vertices_len * sizeof (float), vertices, GL_STATIC_DRAW); - glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof (float), 0); - glEnableVertexAttribArray (0); - - return mesh; -} - -void -Mesh_draw (Mesh *mesh) -{ - glBindBuffer (GL_ARRAY_BUFFER, mesh->vbo); - glDrawArrays (GL_TRIANGLES, 0, mesh->vertices_len); -} diff --git a/game/src/mesh.h b/game/src/mesh.h deleted file mode 100644 index bb36702..0000000 --- a/game/src/mesh.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -#include "util.h" - -typedef struct Mesh -{ - size_t vertices_len; - float *vertices; - GLuint vbo; -} Mesh; - -Mesh Mesh_new (size_t vertices_len, float *vertices); -void Mesh_draw (Mesh *mesh); diff --git a/game/src/program.c b/game/src/program.c index e220ccc..b2adf9b 100644 --- a/game/src/program.c +++ b/game/src/program.c @@ -72,6 +72,12 @@ program_create (const char *v_src, const char *f_src) return program; } +void +program_set_vec4 (int program, const char *name, float x, float y, float z, float w) +{ + glUniform4f (glGetUniformLocation (program, name), x, y, z, w); +} + void program_set_int_array (int program, const char *name, size_t count, int *value) { @@ -104,26 +110,53 @@ gl_type_to_string (GLenum type) void program_print (int program) +/* This function assumes that `program' is the active program. */ { - int bufsize; - glGetProgramiv (program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &bufsize); - char name[bufsize]; - - int uniform_no, attribute_no; - glGetProgramiv (program, GL_ACTIVE_UNIFORMS, &uniform_no); - glGetProgramiv (program, GL_ACTIVE_ATTRIBUTES, &attribute_no); + INFO ("== Program %d ==", program); - INFO ("== Program %d: %d active attribute(s) / %d active uniform(s) ==", program, attribute_no, uniform_no); + int attr_len; + glGetProgramiv (program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &attr_len); + char attr[attr_len]; + + int attribute_no; + glGetProgramiv (program, GL_ACTIVE_ATTRIBUTES, &attribute_no); GLenum type; for (GLint i = 0; i < attribute_no; i++) { - glGetActiveAttrib (program, i, bufsize, NULL, NULL, &type, name); - INFO ("Attribute #%d: %s %s", i, gl_type_to_string (type), name); + glGetActiveAttrib (program, i, attr_len, NULL, NULL, &type, attr); + INFO ("Attribute #%d: %s %s", i, gl_type_to_string (type), attr); } + + int uniform_len; + glGetProgramiv (program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniform_len); + char uniform[uniform_len]; + + int uniform_no; + glGetProgramiv (program, GL_ACTIVE_UNIFORMS, &uniform_no); + + float *vec = malloc (sizeof (float) * 4); for (GLint i = 0; i < uniform_no; i++) { - glGetActiveUniform (program, i, bufsize, NULL, NULL, &type, name); - INFO ("Uniform #%d: %s %s", i, gl_type_to_string (type), name); + glGetActiveUniform (program, i, uniform_len, NULL, NULL, &type, uniform); + + switch (type) + { + case GL_FLOAT_VEC3: + glGetUniformfv (program, glGetUniformLocation (program, uniform), vec); + INFO ("Uniform #%d: %s %s = (%5.1f,%5.1f,%5.1f)", i, gl_type_to_string (type), + uniform, vec[0], vec[1], vec[2]); + break; + case GL_FLOAT_VEC4: + glGetUniformfv (program, glGetUniformLocation (program, uniform), vec); + INFO ("Uniform #%d: %s %s = (%5.1f,%5.1f,%5.1f,%5.1f)", i, gl_type_to_string (type), + uniform, vec[0], vec[1], vec[2], vec[3]); + break; + default: + INFO ("Uniform #%d: %s %s", i, gl_type_to_string (type), uniform); + break; + } } + + free (vec); } diff --git a/game/src/program.h b/game/src/program.h index d2ed27b..c34f206 100644 --- a/game/src/program.h +++ b/game/src/program.h @@ -12,5 +12,6 @@ void shader_fail (int shader); void program_fail (int program); int program_create (const char *v_src, const char *f_src); void program_set_int_array (int program, const char *name, size_t count, int *value); +void program_set_vec4 (int program, const char *name, float x, float y, float z, float w); void program_set_mat4 (int program, const char *name, mat4_t value); void program_print (int program); diff --git a/game/src/resources.c b/game/src/resources.c index 4800ed6..3c505f4 100644 --- a/game/src/resources.c +++ b/game/src/resources.c @@ -80,6 +80,7 @@ Resources_init () Resources_load_texture ("res/textures/dirt.png"); Resources_load_texture ("res/textures/drygrass.png"); Resources_load_texture ("res/textures/grass.png"); + Resources_load_texture ("res/textures/rock_cement.png"); Resources_load_texture ("res/textures/asphalt_gravel.png"); } diff --git a/game/src/util.h b/game/src/util.h index 671ae37..3ccb578 100644 --- a/game/src/util.h +++ b/game/src/util.h @@ -16,3 +16,12 @@ #define FATAL(fmt, args...) (fprintf (stderr, COLOR_RED "[!] %s:%d:%s(): " COLOR_RESET fmt "\n", __FILE__, __LINE__, __func__, ##args), exit (-1)) #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +typedef struct ivec2_t { int x; int y; } ivec2_t; + +static inline ivec2_t +ivec2 (int x, int y) +{ + ivec2_t v = { x, y }; + return v; +}