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+