#include #include #include #include "voxel.h" #include "list.h" #include "cube.h" #include "mesh.h" Chunk *chunk_init(int x, int y, int z) { Chunk *chunk = malloc(sizeof(Chunk)); chunk->x = x; chunk->y = y; chunk->z = z; memset(chunk->blocks, AIR, sizeof(chunk->blocks)); return chunk; } void chunk_free(Chunk *chunk) { free(chunk); } void chunk_generate(Chunk *chunk) { int size = sizeof(chunk->blocks); for (int i = 0; i < size; i++) { int x = i % CHUNK_SIZE; int z = (i / CHUNK_SIZE) % CHUNK_SIZE; int y = i / (CHUNK_SIZE * CHUNK_SIZE); char block = AIR; int temp = x + z - y; if (temp > 16) block = DIRT; chunk->blocks[i] = block; } } typedef struct { Chunk *chunk; List pos; List data; int vertex_count; } MeshState; static void add_vertex(MeshState *state, const vec3 pos, const vec3 xyz, unsigned int data) { list_pushf(&state->pos, pos[0] + xyz[0]); list_pushf(&state->pos, pos[1] + xyz[1]); list_pushf(&state->pos, pos[2] + xyz[2]); list_pushu(&state->data, data); state->vertex_count++; } static void add_quad(MeshState *state, const vec3 xyz, Face face, Block block) { unsigned int data = (face << 2) | block; const vec3 *verts = CUBE[face]; add_vertex(state, verts[0], xyz, data); add_vertex(state, verts[1], xyz, data); add_vertex(state, verts[2], xyz, data); add_vertex(state, verts[3], xyz, data); add_vertex(state, verts[4], xyz, data); add_vertex(state, verts[5], xyz, data); } Mesh chunk_mesh(Chunk *chunk) { MeshState state; state.chunk = chunk; state.vertex_count = 0; list_initf(&state.pos); list_initu(&state.data); int size = sizeof(chunk->blocks); for (int i = 0; i < size; i++) { int x = i % CHUNK_SIZE; int z = (i / CHUNK_SIZE) % CHUNK_SIZE; int y = i / (CHUNK_SIZE * CHUNK_SIZE); vec3 xyz = { x, y, z }; Block block = chunk->blocks[i]; if (block == AIR) continue; Block px = chunk_at(chunk, x + 1, y, z); Block nx = chunk_at(chunk, x - 1, y, z); Block py = chunk_at(chunk, x, y + 1, z); Block ny = chunk_at(chunk, x, y - 1, z); Block pz = chunk_at(chunk, x, y, z + 1); Block nz = chunk_at(chunk, x, y, z - 1); if (px == AIR) add_quad(&state, xyz, POS_X, block); if (nx == AIR) add_quad(&state, xyz, NEG_X, block); if (py == AIR) add_quad(&state, xyz, POS_Y, block); if (ny == AIR) add_quad(&state, xyz, NEG_Y, block); if (pz == AIR) add_quad(&state, xyz, POS_Z, block); if (nz == AIR) add_quad(&state, xyz, NEG_Z, block); } Mesh mesh; mesh_init(&mesh, state.vertex_count); mesh_storef(&mesh, state.pos.fdata, state.pos.len, 3); mesh_storeu(&mesh, state.data.udata, state.data.len, 1); mesh_finish(); list_free(&state.pos); list_free(&state.data); return mesh; } Block chunk_at(Chunk *chunk, int x, int y, int z) { if (x < 0 || x >= CHUNK_SIZE) return AIR; if (y < 0 || y >= CHUNK_SIZE) return AIR; if (z < 0 || z >= CHUNK_SIZE) return AIR; int i = 0; i += x; i += z * CHUNK_SIZE; i += y * CHUNK_SIZE * CHUNK_SIZE; return chunk->blocks[i]; }