summaryrefslogtreecommitdiff
path: root/state_mainstate/src
diff options
context:
space:
mode:
author0undefined <oscar@nelin.dk>2026-03-03 01:17:23 +0000
committer0undefined <oscar@nelin.dk>2026-03-03 01:17:23 +0000
commite57736f1b3bf1cc2f46276bdba3b62b7b6365ff7 (patch)
treee99a64a960e58c7f04dc3ffd7dda6972f06a47db /state_mainstate/src
parenteef15506347455593d0daf1159eaa1b2c5097802 (diff)
Cull blocks
Diffstat (limited to 'state_mainstate/src')
-rw-r--r--state_mainstate/src/mainstate.c15
-rw-r--r--state_mainstate/src/worldgen.c221
2 files changed, 226 insertions, 10 deletions
diff --git a/state_mainstate/src/mainstate.c b/state_mainstate/src/mainstate.c
index fc3a2a8..172f3a7 100644
--- a/state_mainstate/src/mainstate.c
+++ b/state_mainstate/src/mainstate.c
@@ -261,7 +261,7 @@ void mainstate_init(Window *restrict w, mainstate_state *state, void* arg) {
/// Setup the camera
// Set the position (it is zero initialized)
- glm_vec3_copy((vec3){CHUNK_WIDTH / 2.f, CHUNK_HEIGHT / 4.f + 4.f, CHUNK_LENGTH / 2.f}, state->c.pos);
+ glm_vec3_copy((vec3){CHUNK_WIDTH * WORLD_WIDTH / 2.f, CHUNK_HEIGHT / 4.f + 4.f, CHUNK_LENGTH * WORLD_LENGTH / 2.f}, state->c.pos);
// Copy to the desired position
glm_vec3_copy(state->c.pos, state->cam_pos);
@@ -330,6 +330,8 @@ void mainstate_init(Window *restrict w, mainstate_state *state, void* arg) {
}
gen_terrain(state->world);
+ usize total = 0;
+ usize culled = 0;
for (isize i = 0; i < WORLD_SIZE * CHUNK_SIZE; i++) {
if (state->world[i] == BLOCK_none) continue;
@@ -349,7 +351,14 @@ void mainstate_init(Window *restrict w, mainstate_state *state, void* arg) {
Transform t = {
.position = {(float)x, (float)y, (float)z},
};
- switch (state->world[i]) {
+ if (state->world[i] & ((1 << 5) - 1)) {
+ total++;
+ }
+ if (SURROUNDED(state->world[i])) {
+ culled++;
+ continue;
+ }
+ switch (state->world[i] & ((1 << 5) - 1)) {
case BLOCK_grass:
if (-1 == renderbatch_add(&(state->terrain), &(state->objects[0]), &t)) {
ERROR("Failed to add model 0 to render batch!");
@@ -366,6 +375,8 @@ void mainstate_init(Window *restrict w, mainstate_state *state, void* arg) {
}
}
+ INFO("Culled %u / %u (%.2f)", culled, total, (float)culled / (float)total);
+
// Create the render object from the buffer
renderbatch_refresh(&(state->terrain));
state->terrain.renderobj = RenderObject_new(
diff --git a/state_mainstate/src/worldgen.c b/state_mainstate/src/worldgen.c
index 6e5b9c1..51ed21a 100644
--- a/state_mainstate/src/worldgen.c
+++ b/state_mainstate/src/worldgen.c
@@ -44,28 +44,39 @@ static usize global_idx(ivec3 pos) {
}
// Chunks are laid out in worldspace as [c1, ..., cN]
-static void gen_chunk(u8 *chunk, usize z, usize x) {
+static void gen_chunk(u32 *chunk, usize z, usize x) {
// Flat chunks
for (usize yy = 0; yy < CHUNK_HEIGHT / 4; yy++) {
for (usize zz = 0; zz < CHUNK_LENGTH; zz++) {
for (usize xx = 0; xx < CHUNK_WIDTH; xx++) {
- chunk[yy * CHUNK_LENGTH * CHUNK_WIDTH
- + zz * CHUNK_WIDTH
- + xx] = BLOCK_grass;
+ ivec3 pos = {xx,yy,zz};
+ chunk[global_idx(pos)] = BLOCK_grass;
+ //chunk[yy * CHUNK_LENGTH * CHUNK_WIDTH
+ // + zz * CHUNK_WIDTH
+ // + xx] = BLOCK_grass;
}
}
}
+ for (usize zz = 0; zz < CHUNK_LENGTH; zz++) {
+ for (usize xx = 0; xx < CHUNK_WIDTH; xx++) {
+ if (zz % 2 != 0) continue;
+ if (xx % 2 != 0) continue;
+ chunk[(CHUNK_HEIGHT / 4 + 0) * CHUNK_LENGTH * CHUNK_WIDTH
+ + zz * CHUNK_WIDTH
+ + xx] = BLOCK_rock;
+ }
+ }
}
-void gen_terrain(u8 *world) {
+void gen_terrain(u32 *world) {
if (world == NULL) {
world = calloc(WORLD_SIZE * CHUNK_SIZE, sizeof(u8));
}
- for (usize z = 0; z < WORLD_WIDTH; z++) {
- for (usize x = 0; x < WORLD_LENGTH; x++) {
+ for (usize z = 0; z < WORLD_LENGTH; z++) {
+ for (usize x = 0; x < WORLD_WIDTH; x++) {
gen_chunk(&world[
- z * WORLD_LENGTH * CHUNK_SIZE
+ z * WORLD_WIDTH * CHUNK_SIZE
+ x * CHUNK_SIZE
], z, x);
}
@@ -97,4 +108,198 @@ void gen_terrain(u8 *world) {
world[global_idx(pos)] = BLOCK_none;
pos[1]++;
world[global_idx(pos)] = BLOCK_none;
+
+
+ // Mask everything
+ for (usize z = 0; z < WORLD_LENGTH; z++) {
+ for (usize x = 0; x < WORLD_WIDTH; x++) {
+
+ u32 * restrict chunk = &world[
+ z * WORLD_WIDTH * CHUNK_SIZE
+ + x * CHUNK_SIZE
+ ];
+
+ for (isize yy = 0; yy < CHUNK_HEIGHT; yy++) {
+ for (isize zz = 0; zz < CHUNK_LENGTH; zz++) {
+ for (isize xx = 0; xx < CHUNK_WIDTH; xx++) {
+
+ u32 mask = 0;
+
+ // TODO: Fix OOB access
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ for (int k = 0; k < 3; k++) {
+ if (i == 0 && yy - 1 < 0) continue;
+ if (j == 0 && zz - 1 < 0) continue;
+ if (k == 0 && xx - 1 < 0) continue;
+ if (i == 2 && yy + 1 >= CHUNK_HEIGHT) continue;
+ if (j == 2 && zz + 1 >= CHUNK_LENGTH) continue;
+ if (k == 2 && xx + 1 >= CHUNK_WIDTH) continue;
+
+ if (
+ chunk[(i + yy - 1) * CHUNK_LENGTH * CHUNK_WIDTH
+ + (j + zz - 1) * CHUNK_WIDTH
+ + (k + xx - 1)] & ((1 << 5) - 1)
+ ) {
+ mask |= 1 << ((i * 9) + j * 3 + k);
+ }
+ }
+ }
+ }
+
+ if (yy == 0) {
+ mask |= FILLED_MASK_BOT;
+ }
+ chunk[yy * CHUNK_LENGTH * CHUNK_WIDTH
+ + zz * CHUNK_WIDTH
+ + xx] |= mask << 5;
+ }
+ }
+ }
+
+ }
+ }
+
+ // Mask chunk borders
+ for (usize z = 0; z < WORLD_LENGTH; z++) {
+ for (usize x = 0; x < WORLD_WIDTH; x++) {
+ u32 * restrict chunk = &world[
+ z * WORLD_WIDTH * CHUNK_SIZE
+ + x * CHUNK_SIZE
+ ];
+
+ // LEFT (-X)
+ if (x > 0) {
+ u32 * restrict lchunk = &world[
+ z * WORLD_WIDTH * CHUNK_SIZE
+ + (x - 1) * CHUNK_SIZE
+ ];
+ // local YZ
+ for (isize ly = 0; ly < CHUNK_HEIGHT; ly++) {
+ for (isize lz = 0; lz < CHUNK_LENGTH; lz++) {
+ u32 mask = 0;
+
+ // neighbouring xy
+ for (isize i = 0; i < 3; i++) {
+ for (isize j = 0; j < 3; j++) {
+ if (i == 0 && ly - 1 < 0) continue;
+ if (j == 0 && lz - 1 < 0) continue;
+ if (i == 2 && ly + 1 >= CHUNK_HEIGHT) continue;
+ if (j == 2 && lz + 1 >= CHUNK_LENGTH) continue;
+
+ ivec3 pos = {CHUNK_WIDTH - 1, i + ly - 1, j + lz - 1};
+ if (lchunk[global_idx(pos)] & (((1 << 5) - 1))) {
+ mask |= 1 << (i * 9 + j * 3);
+ }
+ }
+ }
+ ivec3 pos = {0, ly, lz};
+ chunk[ly * CHUNK_LENGTH * CHUNK_WIDTH
+ + lz * CHUNK_WIDTH
+ + 0] |= mask << 5;
+ }
+ }
+ }
+ // RIGHT (+X)
+ if (x < WORLD_WIDTH - 1) {
+ u32 * restrict rchunk = &world[
+ z * WORLD_WIDTH * CHUNK_SIZE
+ + (x + 1) * CHUNK_SIZE
+ ];
+
+ // local YZ
+ for (isize ly = 0; ly < CHUNK_HEIGHT; ly++) {
+ for (isize lz = 0; lz < CHUNK_LENGTH; lz++) {
+ u32 mask = 0;
+
+ // neighbouring xy
+ for (isize i = 0; i < 3; i++) {
+ for (isize j = 0; j < 3; j++) {
+ if (i == 0 && ly - 1 < 0) continue;
+ if (j == 0 && lz - 1 < 0) continue;
+ if (i == 2 && ly + 1 >= CHUNK_HEIGHT) continue;
+ if (j == 2 && lz + 1 >= CHUNK_LENGTH) continue;
+
+ ivec3 pos = {0, i + ly - 1, j + lz - 1};
+ if (rchunk[global_idx(pos)] & (((1 << 5) - 1))) {
+ mask |= 1 << (i * 9 + j * 3 + 2);
+ }
+ }
+ }
+ ivec3 pos = {CHUNK_WIDTH - 1, ly, lz};
+ chunk[ly * CHUNK_LENGTH * CHUNK_WIDTH
+ + lz * CHUNK_WIDTH
+ + (CHUNK_WIDTH - 1)] |= mask << 5;
+ }
+ }
+ }
+ // BACK (-Z)
+ if (z > 0) {
+ u32 * restrict bchunk = &world[
+ (z - 1) * WORLD_WIDTH * CHUNK_SIZE
+ + x * CHUNK_SIZE
+ ];
+ // local YZ
+ for (isize ly = 0; ly < CHUNK_HEIGHT; ly++) {
+ for (isize lx = 0; lx < CHUNK_LENGTH; lx++) {
+ u32 mask = 0;
+
+ // neighbouring xy
+ for (isize i = 0; i < 3; i++) {
+ for (isize j = 0; j < 3; j++) {
+ if (i == 0 && ly - 1 < 0) continue;
+ if (j == 0 && lx - 1 < 0) continue;
+ if (i == 2 && ly + 1 >= CHUNK_HEIGHT) continue;
+ if (j == 2 && lx + 1 >= CHUNK_WIDTH) continue;
+
+ ivec3 pos = {j + lx - 1, i + ly - 1, CHUNK_LENGTH - 1};
+ if (bchunk[global_idx(pos)] & (((1 << 5) - 1))) {
+ mask |= 1 << (i * 9 + j);
+ }
+ }
+ }
+ ivec3 pos = {lx, ly, 0};
+ chunk[ly * CHUNK_LENGTH * CHUNK_WIDTH
+ + 0
+ + lx] |= mask << 5;
+ }
+ }
+ }
+ // FRONT (+Z)
+ if (z < WORLD_LENGTH - 1) {
+ u32 * restrict rchunk = &world[
+ (z + 1) * WORLD_WIDTH * CHUNK_SIZE
+ + x * CHUNK_SIZE
+ ];
+
+ // local YZ
+ for (isize ly = 0; ly < CHUNK_HEIGHT; ly++) {
+ for (isize lx = 0; lx < CHUNK_WIDTH; lx++) {
+ u32 mask = 0;
+
+ // neighbouring xy
+ for (isize i = 0; i < 3; i++) {
+ for (isize j = 0; j < 3; j++) {
+ if (i == 0 && ly - 1 < 0) continue;
+ if (j == 0 && lx - 1 < 0) continue;
+ if (i == 2 && ly + 1 >= CHUNK_HEIGHT) continue;
+ if (j == 2 && lx + 1 >= CHUNK_WIDTH) continue;
+
+ ivec3 pos = {j + lx - 1, i + ly - 1, 0};
+ if (rchunk[global_idx(pos)] & (((1 << 5) - 1))) {
+ mask |= 1 << (i * 9 + j + 6);
+ }
+ }
+ }
+ ivec3 pos = {lx, ly, CHUNK_LENGTH - 1};
+ chunk[ly * CHUNK_LENGTH * CHUNK_WIDTH
+ + (CHUNK_LENGTH - 1) * CHUNK_WIDTH
+ + lx] |= mask << 5;
+ }
+ }
+ }
+
+
+ }
+ }
}