diff options
| author | Aaditya Dhruv <[email protected]> | 2026-01-31 18:34:55 -0600 |
|---|---|---|
| committer | Aaditya Dhruv <[email protected]> | 2026-01-31 18:34:55 -0600 |
| commit | d5cad0e247ffffd4e985696809e46805177c6940 (patch) | |
| tree | 519babc838c7d1cd620b61761245aca862e6e08a | |
| parent | b20a6103cb202c1721aa2d300b1e7bdafef3366d (diff) | |
Bugfixes, infinite loading works
| -rw-r--r-- | src/chunk.c | 49 | ||||
| -rw-r--r-- | src/chunk.h | 2 | ||||
| -rw-r--r-- | src/engine.c | 34 | ||||
| -rw-r--r-- | src/engine.h | 2 | ||||
| -rw-r--r-- | src/input.c | 2 | ||||
| -rw-r--r-- | src/world.c | 2 |
6 files changed, 60 insertions, 31 deletions
diff --git a/src/chunk.c b/src/chunk.c index 67631e9..d67d8cb 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -1,5 +1,6 @@ #include "chunk.h" #include "block.h" +#include "cglm/io.h" #include "cglm/types.h" #include "cglm/vec2.h" #include "cglm/vec3.h" @@ -122,9 +123,13 @@ int _chunk_check_neighbor_block(struct world* world, struct chunk* chunk, vec3 c glm_vec2_add(left, chunk->coord, c); int neighbor[] = { c[0], c[1] }; struct chunk* left_chunk = { 0 }; - world_get_chunk(world, neighbor, &chunk); - // If unloaded, we don't care, it's not being rendered, so mark as no neighbor - if (left_chunk == NULL || left_chunk->loaded == 0) { + world_get_chunk(world, neighbor, &left_chunk); + // If not created, we don't care, it's not being rendered, so mark as no neighbor + // TODO: Previously had chunk->loaded == 0, but this causes a problem. When we move + // from one chunk to another, everything gets unloaded, and then we start loading everything. + // This means that sometimes because of order of evaluation a chunk might think it's neighbor + // isn't loaded even though it will be + if (left_chunk == NULL) { return 0; } // Otherwise we check if the neighbor block exists @@ -137,9 +142,9 @@ int _chunk_check_neighbor_block(struct world* world, struct chunk* chunk, vec3 c glm_vec2_add(right, chunk->coord, c); int neighbor[] = { c[0], c[1] }; struct chunk* right_chunk = { 0 }; - world_get_chunk(world, neighbor, &chunk); + world_get_chunk(world, neighbor, &right_chunk); // If unloaded, we don't care, it's not being rendered, so mark as no neighbor - if (right_chunk == NULL || right_chunk->loaded == 0) { + if (right_chunk == NULL) { return 0; } // Otherwise we check if the neighbor block exists @@ -152,9 +157,9 @@ int _chunk_check_neighbor_block(struct world* world, struct chunk* chunk, vec3 c glm_vec2_add(bottom, chunk->coord, c); int neighbor[] = { c[0], c[1] }; struct chunk* bottom_chunk = { 0 }; - world_get_chunk(world, neighbor, &chunk); + world_get_chunk(world, neighbor, &bottom_chunk); // If unloaded, we don't care, it's not being rendered, so mark as no neighbor - if (bottom_chunk == NULL || bottom_chunk->loaded == 0) { + if (bottom_chunk == NULL) { return 0; } // Otherwise we check if the neighbor block exists @@ -167,9 +172,9 @@ int _chunk_check_neighbor_block(struct world* world, struct chunk* chunk, vec3 c glm_vec2_add(top, chunk->coord, c); int neighbor[] = { c[0], c[1] }; struct chunk* top_chunk = { 0 }; - world_get_chunk(world, neighbor, &chunk); + world_get_chunk(world, neighbor, &top_chunk); // If unloaded, we don't care, it's not being rendered, so mark as no neighbor - if (top_chunk == NULL || top_chunk->loaded == 0) { + if (top_chunk == NULL) { return 0; } // Otherwise we check if the neighbor block exists @@ -199,11 +204,11 @@ int _chunk_check_neighbor_block(struct world* world, struct chunk* chunk, vec3 c void _chunk_plains_gen(struct chunk* chunk) { // ============ KNOBS ============ // Minimum ground - int z = 2; + int z = 20; // Min POI block height - int poi_min = 3; + int poi_min = 23; // Max POI block height - int poi_max = 5; + int poi_max = 25; // Descent/Ascent rate float m = -.5; memset(chunk->blocks, 0, CHUNK_HEIGHT * CHUNK_LENGTH * CHUNK_WIDTH * sizeof(struct block*)); @@ -227,7 +232,6 @@ void _chunk_plains_gen(struct chunk* chunk) { } } } - chunk->loaded = 1; } @@ -261,7 +265,18 @@ float* _chunk_face_add(float* face, int size, vec3 pos) { * NOTE: GPU */ void chunk_load(struct world* world, struct chunk *chunk, int coord[2]) { - fprintf(stderr, "Loaded chunk (%d, %d)\n", coord[0], coord[1]); + // If we are already loaded, no need to do any GPU work at all. Just update the coordinates + if (chunk->loaded == 1) { + vec3 translation = {CHUNK_WIDTH * coord[0], 0, - (CHUNK_LENGTH * coord[1])}; + // Set the matrix for world coordinate translation + glm_mat4_identity(chunk->model); + glm_translate(chunk->model, translation); + chunk->loaded = 1; + chunk->staged_for_load = 0; + return; + + } + // fprintf(stderr, "Loaded chunk (%d, %d)\n", coord[0], coord[1]); // ================ OpenGL work ================ // Initalize vertices and vertex order vectors. These will be dynamically // sized buffer data we send to the GPU @@ -445,8 +460,8 @@ void chunk_load(struct world* world, struct chunk *chunk, int coord[2]) { } float tmp_vertex[vector_length(vertices) * sizeof(front_face)]; int tmp_order[vector_length(vertex_order) * sizeof(vertex_draw_order)]; - fprintf(stderr, "Chunk blk_c: %d v_s: %d, v_o: %d\n", blk_c, vector_length(vertices) / 6, vector_length(vertex_order) / 6); - fprintf(stderr, "%d|%d|%d|%d|%d|%d|", v_count[0], v_count[1], v_count[2], v_count[3], v_count[4], v_count[5]); + // fprintf(stderr, "Chunk blk_c: %d v_s: %d, v_o: %d\n", blk_c, vector_length(vertices) / 6, vector_length(vertex_order) / 6); + // fprintf(stderr, "%d|%d|%d|%d|%d|%d|", v_count[0], v_count[1], v_count[2], v_count[3], v_count[4], v_count[5]); for (int i = 0; i < vector_length(vertices); i++) { float* face = vector_get(vertices, i); // Copy from heap mem to tmp buffer, and then free @@ -497,6 +512,7 @@ void chunk_load(struct world* world, struct chunk *chunk, int coord[2]) { glm_mat4_identity(chunk->model); glm_translate(chunk->model, translation); chunk->loaded = 1; + chunk->staged_for_load = 0; } void chunk_draw(struct chunk* chunk, struct shader* shader, struct texture* texture) { @@ -515,6 +531,7 @@ void chunk_unload(struct chunk* chunk) { // Clear VAO glDeleteVertexArrays(1, &chunk->_vao); chunk->loaded = 0; + chunk->staged_for_load = 0; } // Regenerate chunk data diff --git a/src/chunk.h b/src/chunk.h index c22fd36..52c0df3 100644 --- a/src/chunk.h +++ b/src/chunk.h @@ -34,7 +34,7 @@ struct chunk { enum biome biome; vec2 coord; int loaded; - int dirty; + int staged_for_load; }; /** diff --git a/src/engine.c b/src/engine.c index 551ab65..0dd8089 100644 --- a/src/engine.c +++ b/src/engine.c @@ -46,7 +46,7 @@ int engine_init(struct engine *engine) { // Setup camera camera_init(&engine->camera); - vec3 camera_pos = { 0.0f, 15.0f, 0.0f }; + vec3 camera_pos = { 0.0f, 40.0f, 0.0f }; camera_set_position(engine->camera, camera_pos); // Setup root chunk @@ -72,9 +72,6 @@ void engine_update(struct engine* engine) { //NOTE: OpenGL FLIP int curr_chunk[2] = { floorf(engine->camera->position[0] / (float)CHUNK_WIDTH), floorf(-engine->camera->position[2] / (float)CHUNK_LENGTH) }; // Chunk update - struct chunk* c = {0}; - world_get_chunk(engine->world, curr_chunk, &c); - // We moved a chunk - load new chunks with chunk_load if (engine->curr_chunk[0] != curr_chunk[0] || engine->curr_chunk[1] != curr_chunk[1]) { fprintf(stderr, "CHUNK Update! From (%d, %d) to (%d, %d)\n", @@ -82,6 +79,17 @@ void engine_update(struct engine* engine) { engine->curr_chunk[1], curr_chunk[0], curr_chunk[1]); + // Stage relevant chunks for loading + for (int i = -CHUNK_DISTANCE; i <= CHUNK_DISTANCE; i++) { + for (int j = -CHUNK_DISTANCE; j <= CHUNK_DISTANCE; j++) { + struct chunk* chunk; + int chunk_coord[2] = { curr_chunk[0] + i, curr_chunk[1] + j }; + world_get_chunk(engine->world, chunk_coord, &chunk); + // Stage for loading chunk + chunk->staged_for_load = 1; + // fprintf(stderr, "Staged (%d, %d)\n", chunk_coord[0], chunk_coord[1]); + } + } // Unload existing chunks for (int i = -CHUNK_DISTANCE; i <= CHUNK_DISTANCE; i++) { for (int j = -CHUNK_DISTANCE; j <= CHUNK_DISTANCE; j++) { @@ -89,22 +97,25 @@ void engine_update(struct engine* engine) { int chunk_coord[2] = { engine->curr_chunk[0] + i, engine->curr_chunk[1] + j }; world_get_chunk(engine->world, chunk_coord, &chunk); // unload chunk - // TODO: Fix some VAO/VBO bug when negative y - chunk_unload(chunk); + if (chunk->staged_for_load == 0) { + // fprintf(stderr, "Unloaded (%d, %d)\n", chunk_coord[0], chunk_coord[1]); + chunk_unload(chunk); + } } } - // Update the curr_chunk - memcpy(engine->curr_chunk, curr_chunk, sizeof(vec2)); - // Load chunks of CHUNK_DISTANCE around curr_chunk + // Load chunks that are needed for (int i = -CHUNK_DISTANCE; i <= CHUNK_DISTANCE; i++) { for (int j = -CHUNK_DISTANCE; j <= CHUNK_DISTANCE; j++) { struct chunk* chunk; - int chunk_coord[2] = { engine->curr_chunk[0] + i, engine->curr_chunk[1] + j }; + int chunk_coord[2] = { curr_chunk[0] + i, curr_chunk[1] + j }; world_get_chunk(engine->world, chunk_coord, &chunk); - // Load chunk + // Load chunks - if already loaded will only update coords chunk_load(engine->world, chunk, chunk_coord); + fprintf(stderr, "Loaded (%d, %d)\n", chunk_coord[0], chunk_coord[1]); } } + // Update the curr_chunk + memcpy(engine->curr_chunk, curr_chunk, sizeof(vec2)); } } @@ -132,7 +143,6 @@ void engine_start(struct engine* engine) { frames = 0; frame_last_time = now; fprintf(stderr, "FPS: %.2f\n", fps); - glm_vec3_print(engine->camera->position, stderr); fprintf(stderr, "x: %d, y: %d\n", engine->curr_chunk[0], engine->curr_chunk[1]); } diff --git a/src/engine.h b/src/engine.h index 413c74f..115f06f 100644 --- a/src/engine.h +++ b/src/engine.h @@ -8,7 +8,7 @@ // We want a square around curr_chunk, and a side of the square will be 1 // (center chunk) + 2 * CHUNK_DISTANCE (either side of center) // loaded chunks = (1 + CHUNK_DISTANCE * 2)^2 -#define CHUNK_DISTANCE 0 +#define CHUNK_DISTANCE 10 struct engine { struct window* window; diff --git a/src/input.c b/src/input.c index 06f63a5..472b043 100644 --- a/src/input.c +++ b/src/input.c @@ -5,6 +5,7 @@ #include <SDL2/SDL_events.h> #include <SDL2/SDL_mouse.h> #include <SDL2/SDL_stdinc.h> +#include <SDL2/SDL_video.h> pthread_t input_init(struct engine* engine) { pthread_t thread; @@ -17,6 +18,7 @@ void input_join(pthread_t thread, struct engine* engine) { void input_handle(struct engine *engine) { SDL_Event event; SDL_SetRelativeMouseMode(SDL_TRUE); + SDL_SetWindowMouseGrab(engine->window->window, SDL_TRUE); while (engine->game_loop) { // Quit game // TODO: Locks? diff --git a/src/world.c b/src/world.c index 4ce248b..8ae323e 100644 --- a/src/world.c +++ b/src/world.c @@ -5,7 +5,7 @@ #include <string.h> // LOAD_DISTANCE determines how many chunks are loaded on world creation -#define LOAD_DISTANCE 10 +#define LOAD_DISTANCE 1 int world_init(int32_t seed, struct world** world) { srand(seed); |
