commit 618a7fd
uint
·
2026-07-30 22:18:16 +0000 UTC
parent 331fa1e
add chunks
5 files changed,
+150,
-52
+45,
-52
1@@ -6,46 +6,37 @@
2 #include "client/camera.h"
3 #include "renderer/renderer.h"
4 #include "renderer/test_block.h"
5+#include "world/block.h"
6+#include "world/chunk.h"
7
8-typedef struct {
9- MGMesh mesh;
10- MGTexture texture;
11-} Block;
12-
13-static Block brick = { MGMESH_INVALID, MGTEXTURE_INVALID };
14-static Block dirt = { MGMESH_INVALID, MGTEXTURE_INVALID };
15-static Block stone = { MGMESH_INVALID, MGTEXTURE_INVALID };
16+static MGTexture block_textures[BLOCK_LAST];
17+static MGMesh standard_block_mesh;
18+static Chunk chunk;
19 static MGCamera cam;
20
21 void test_scene_create(void)
22 {
23- brick.mesh = block_mesh_create();
24- if (brick.mesh == MGMESH_INVALID)
25+ standard_block_mesh = block_mesh_create();
26+ if (standard_block_mesh == MGMESH_INVALID)
27 mg_die(MG_ERR_MESH_CREATE, "Failed to create test block mesh");
28
29- brick.texture = renderer_texture_load("assets/resourcepacks/default/blocks/brick.png");
30- if (brick.texture == MGTEXTURE_INVALID)
31- mg_die(MG_ERR_TEXTURE_LOAD, "Failed to load test block texture");
32-
33- dirt.mesh = block_mesh_create();
34- if (dirt.mesh == MGMESH_INVALID)
35- mg_die(MG_ERR_MESH_CREATE, "Failed to create test block mesh");
36+ block_textures[BLOCK_BRICK] = renderer_texture_load("assets/resourcepacks/default/blocks/brick.png");
37+ if (block_textures[BLOCK_BRICK] == MGTEXTURE_INVALID)
38+ mg_die(MG_ERR_TEXTURE_LOAD, "Failed to load brick texture");
39
40- dirt.texture = renderer_texture_load("assets/resourcepacks/default/blocks/dirt.png");
41- if (dirt.texture == MGTEXTURE_INVALID)
42- mg_die(MG_ERR_TEXTURE_LOAD, "Failed to load test block texture");
43+ block_textures[BLOCK_DIRT] = renderer_texture_load("assets/resourcepacks/default/blocks/dirt.png");
44+ if (block_textures[BLOCK_DIRT] == MGTEXTURE_INVALID)
45+ mg_die(MG_ERR_TEXTURE_LOAD, "Failed to load dirt texture");
46
47- stone.mesh = block_mesh_create();
48- if (stone.mesh == MGMESH_INVALID)
49- mg_die(MG_ERR_MESH_CREATE, "Failed to create test block mesh");
50+ block_textures[BLOCK_STONE] = renderer_texture_load("assets/resourcepacks/default/blocks/stone.png");
51+ if (block_textures[BLOCK_STONE] == MGTEXTURE_INVALID)
52+ mg_die(MG_ERR_TEXTURE_LOAD, "Failed to load stone texture");
53
54- stone.texture = renderer_texture_load("assets/resourcepacks/default/blocks/stone.png");
55- if (stone.texture == MGTEXTURE_INVALID)
56- mg_die(MG_ERR_TEXTURE_LOAD, "Failed to load test block texture");
57+ chunk_create(&chunk);
58
59- camera_init(&cam, MG_V3(3.0f, 3.0f, 3.0f));
60- cam.yaw = MG_AngleDeg(-140.0f);
61- cam.pitch = MG_AngleDeg(-20.0f);
62+ camera_init(&cam, MG_V3(8.0f, 38.0f, 24.0f));
63+ cam.yaw = MG_AngleDeg(-180.0f);
64+ cam.pitch = MG_AngleDeg(-25.0f);
65 }
66
67 void test_scene_draw(MGContext* ctx)
68@@ -56,7 +47,11 @@ void test_scene_draw(MGContext* ctx)
69 MGMat4 mvp;
70 i32 width;
71 i32 height;
72+ i32 x;
73+ i32 y;
74+ i32 z;
75 float aspect;
76+ BlockType block;
77
78 platform_get_drawable_size(ctx, &width, &height);
79
80@@ -68,35 +63,33 @@ void test_scene_draw(MGContext* ctx)
81 proj = camera_get_proj(&cam, aspect);
82 view = camera_get_view(&cam);
83
84- model = MG_Translate(MG_V3(0.0f, 0.0f, 0.0f));
85- mvp = MG_MulM4(proj, MG_MulM4(view, model));
86- renderer_mesh_draw(brick.mesh, brick.texture, &mvp);
87+ for (z = 0; z < CHUNK_DEPTH; z++) {
88+ for (y = 0; y < CHUNK_HEIGHT; y++) {
89+ for (x = 0; x < CHUNK_WIDTH; x++) {
90+ block = chunk_get(&chunk, x, y, z);
91
92- model = MG_Translate(MG_V3(1.0f, 0.0f, 0.0f));
93- mvp = MG_MulM4(proj, MG_MulM4(view, model));
94- renderer_mesh_draw(dirt.mesh, dirt.texture, &mvp);
95+ if (block == BLOCK_AIR)
96+ continue;
97
98- model = MG_Translate(MG_V3(2.0f, 0.0f, 0.0f));
99- mvp = MG_MulM4(proj, MG_MulM4(view, model));
100- renderer_mesh_draw(stone.mesh, stone.texture, &mvp);
101+ model = MG_Translate(MG_V3(x, y, z));
102+ mvp = MG_MulM4(proj, MG_MulM4(view, model));
103+ renderer_mesh_draw(standard_block_mesh, block_textures[block], &mvp);
104+ }
105+ }
106+ }
107 }
108
109 void test_scene_destroy(void)
110 {
111- renderer_mesh_destroy(brick.mesh);
112- renderer_texture_destroy(brick.texture);
113- brick.mesh = MGMESH_INVALID;
114- brick.texture = MGTEXTURE_INVALID;
115-
116- renderer_mesh_destroy(dirt.mesh);
117- renderer_texture_destroy(dirt.texture);
118- dirt.mesh = MGMESH_INVALID;
119- dirt.texture = MGTEXTURE_INVALID;
120-
121- renderer_mesh_destroy(stone.mesh);
122- renderer_texture_destroy(stone.texture);
123- stone.mesh = MGMESH_INVALID;
124- stone.texture = MGTEXTURE_INVALID;
125+ renderer_texture_destroy(block_textures[BLOCK_BRICK]);
126+ renderer_texture_destroy(block_textures[BLOCK_DIRT]);
127+ renderer_texture_destroy(block_textures[BLOCK_STONE]);
128+ renderer_mesh_destroy(standard_block_mesh);
129+
130+ block_textures[BLOCK_BRICK] = MGTEXTURE_INVALID;
131+ block_textures[BLOCK_DIRT] = MGTEXTURE_INVALID;
132+ block_textures[BLOCK_STONE] = MGTEXTURE_INVALID;
133+ standard_block_mesh = MGMESH_INVALID;
134 }
135
136 #endif /* TEST_SCENE_H */
+14,
-0
1@@ -0,0 +1,14 @@
2+#ifndef WORLD_BLOCK_H
3+#define WORLD_BLOCK_H
4+
5+typedef enum {
6+ BLOCK_AIR,
7+ BLOCK_BRICK,
8+ BLOCK_DIRT,
9+ BLOCK_STONE,
10+
11+ BLOCK_LAST
12+} BlockType;
13+
14+#endif /* WORLD_BLOCK_H */
15+
+32,
-0
1@@ -0,0 +1,32 @@
2+#ifndef CHUNK_H
3+#define CHUNK_H
4+
5+#include "types.h"
6+#include "world/block.h"
7+
8+#define CHUNK_WIDTH 16
9+#define CHUNK_HEIGHT 32
10+#define CHUNK_DEPTH 16
11+
12+typedef struct {
13+ BlockType blocks[CHUNK_WIDTH][CHUNK_HEIGHT][CHUNK_DEPTH];
14+} Chunk;
15+
16+/* create a new chunk
17+ just stone and dirt with a hint of brick for now */
18+void chunk_create(Chunk* chunk);
19+
20+/* get the block at specified position
21+ TODO? should we use x, y, z or a vec3? c89 doesnt
22+ have compound literals so it may be a pain in
23+ the future? who knows */
24+BlockType chunk_get(const Chunk* chunk, i32 x, i32 y, i32 z);
25+
26+/* set the block at specified position
27+ TODO? should we use x, y, z or a vec3? c89 doesnt
28+ have compound literals so it may be a pain in
29+ the future? who knows */
30+void chunk_set(Chunk* chunk, i32 x, i32 y, i32 z, BlockType block);
31+
32+#endif /* CHUNK_H */
33+
+1,
-0
1@@ -15,6 +15,7 @@ renderer_backend = get_option('renderer')
2 sources = [
3 'source/main.c',
4 'source/util.c',
5+ 'source/world/chunk.c',
6 'source/client/camera.c',
7 'source/platform/platform.c',
8 'vendor/stb_image_c89.c',
+58,
-0
1@@ -0,0 +1,58 @@
2+#include "world/chunk.h"
3+
4+void chunk_create(Chunk* chunk)
5+{
6+ i32 x;
7+ i32 y;
8+ i32 z;
9+
10+ for (z = 0; z < CHUNK_DEPTH; z++) {
11+ for (x = 0; x < CHUNK_WIDTH; x++) {
12+ for (y = 0; y < CHUNK_HEIGHT - 5; y++)
13+ chunk_set(chunk, x, y, z, BLOCK_STONE);
14+
15+ chunk_set(chunk, x, CHUNK_HEIGHT - 5, z, BLOCK_DIRT);
16+ }
17+ }
18+
19+ chunk_set(chunk, 6, 28, 8, BLOCK_BRICK);
20+ chunk_set(chunk, 8, 28, 8, BLOCK_BRICK);
21+ chunk_set(chunk, 7, 29, 8, BLOCK_BRICK);
22+ chunk_set(chunk, 7, 30, 8, BLOCK_BRICK);
23+ chunk_set(chunk, 7, 31, 8, BLOCK_STONE);
24+}
25+
26+BlockType chunk_get(const Chunk* chunk, i32 x, i32 y, i32 z)
27+{
28+ if (!chunk)
29+ return BLOCK_AIR;
30+
31+ if (x < 0 || x >= CHUNK_WIDTH)
32+ return BLOCK_AIR;
33+
34+ if (y < 0 || y >= CHUNK_HEIGHT)
35+ return BLOCK_AIR;
36+
37+ if (z < 0 || z >= CHUNK_DEPTH)
38+ return BLOCK_AIR;
39+
40+ return chunk->blocks[x][y][z];
41+}
42+
43+void chunk_set(Chunk* chunk, i32 x, i32 y, i32 z, BlockType block)
44+{
45+ if (!chunk)
46+ return;
47+
48+ if (x < 0 || x >= CHUNK_WIDTH)
49+ return;
50+
51+ if (y < 0 || y >= CHUNK_HEIGHT)
52+ return;
53+
54+ if (z < 0 || z >= CHUNK_DEPTH)
55+ return;
56+
57+ chunk->blocks[x][y][z] = block;
58+}
59+