commit ac731f2
shrub
·
2026-08-12 17:04:07 +0000 UTC
parent f31e894
allocate chunk sections on demand to reduce memory usage significantly
5 files changed,
+36,
-12
+3,
-3
1@@ -23,9 +23,9 @@ typedef struct {
2 i32 x;
3 i32 z;
4
5- ChunkSection sections[CHUNK_SECTION_COUNT];
6- u16 section_mask;
7- i8 used;
8+ ChunkSection* sections[CHUNK_SECTION_COUNT];
9+ u16 section_mask;
10+ i8 used;
11 } Chunk;
12
13 /* clear chunk contents and mark unused */
+18,
-3
1@@ -1,3 +1,4 @@
2+#include <stdlib.h>
3 #include <string.h>
4
5 #include "types.h"
6@@ -73,7 +74,7 @@ static ChunkSection* world_chunk_section_find(ClientWorld* world, i32 x, i32 z,
7 if (!chunk || !(chunk->section_mask & (1U << section)))
8 return NULL;
9
10- return &chunk->sections[section];
11+ return chunk->sections[section];
12 }
13
14 /* rebuild chunk section mesh with face culling
15@@ -89,7 +90,10 @@ static i8 world_chunk_section_mesh_create(ClientWorld* world, Chunk* chunk, i32
16 section + neighbour_offsets[face][1]);
17 }
18
19- return chunk_section_mesh_create(&chunk->sections[section], neighbours);
20+ if (!chunk->sections[section])
21+ return 0;
22+
23+ return chunk_section_mesh_create(chunk->sections[section], neighbours);
24 }
25
26 /* rebuild chunk mesh and neighbouring chunk meshes for sections in section_mask
27@@ -191,6 +195,7 @@ i8 world_mesh_create(ClientWorld* world)
28 i8 world_update_chunk(ClientWorld* world, const MCChunkUpdate* update, const u8* data)
29 {
30 Chunk* chunk;
31+ ChunkSection* chunk_section;
32 i32 section;
33 i32 data_section;
34 u16 remesh_mask;
35@@ -215,8 +220,18 @@ i8 world_update_chunk(ClientWorld* world, const MCChunkUpdate* update, const u8*
36 if (!(update->mask & (1U << section)))
37 continue;
38
39+ chunk_section = chunk->sections[section];
40+ if (!chunk_section) {
41+ chunk_section = calloc(1, sizeof(*chunk_section));
42+ if (!chunk_section) {
43+ mg_log(LOG_ERR, "Failed to allocate chunk section");
44+ return 0;
45+ }
46+ chunk->sections[section] = chunk_section;
47+ }
48+
49 /* decode section data into mesh */
50- if (!chunk_section_decode(&chunk->sections[section],
51+ if (!chunk_section_decode(chunk_section,
52 data + (size_t)data_section * MC_CHUNK_SECTION_BLOCK_BYTES,
53 MC_CHUNK_SECTION_BLOCK_BYTES)) {
54 mg_log(LOG_ERR, "Failed to create chunk mesh");
+7,
-2
1@@ -55,7 +55,10 @@ static void create_local_world(void)
2 chunk->used = 1;
3 chunk->x = x;
4 chunk->z = z;
5- chunk_section_create(&chunk->sections[0]);
6+ chunk->sections[0] = calloc(1, sizeof(*chunk->sections[0]));
7+ if (!chunk->sections[0])
8+ mg_die(MG_EC_MESH_CREATE, "Failed to allocate local chunk section");
9+ chunk_section_create(chunk->sections[0]);
10 chunk->section_mask = 1;
11 }
12
13@@ -309,7 +312,9 @@ static void render_world(void)
14 if (!(chunk->section_mask & (1U << section_index)))
15 continue;
16
17- section = &chunk->sections[section_index];
18+ section = chunk->sections[section_index];
19+ if (!section)
20+ continue;
21 model = MG_Translate(MG_V3(chunk->x * CHUNK_WIDTH, section_index * CHUNK_SECTION_HEIGHT,
22 chunk->z * CHUNK_DEPTH));
23 mvp = MG_MulM4(proj, MG_MulM4(view, model));
1@@ -13,8 +13,8 @@
2
3 #define MAX_MESHES (16384)
4 #define MAX_TEXTURES (512)
5-#define S3L_MAX_WIDTH (4096)
6-#define S3L_MAX_HEIGHT (4096)
7+#define S3L_MAX_WIDTH (800)
8+#define S3L_MAX_HEIGHT (600)
9 #define SOFTWARE_MAX_WIDTH (800)
10 #define SOFTWARE_MAX_HEIGHT (600)
11 #define TEXTURE_SAMPLE_PERIOD (4)
+6,
-2
1@@ -75,8 +75,12 @@ void chunk_clear(Chunk* chunk)
2 return;
3
4 for (section = 0; section < CHUNK_SECTION_COUNT; section++) {
5- chunk_section_mesh_destroy(&chunk->sections[section]);
6- memset(&chunk->sections[section], 0, sizeof(chunk->sections[section]));
7+ if (!chunk->sections[section])
8+ continue;
9+
10+ chunk_section_mesh_destroy(chunk->sections[section]);
11+ free(chunk->sections[section]);
12+ chunk->sections[section] = NULL;
13 }
14
15 chunk->section_mask = 0;