refactor: split large functions into smaller ones

This commit is contained in:
catangent 2025-08-03 18:52:11 +01:00
parent c7a194c0d3
commit 35a81340b1
2 changed files with 121 additions and 121 deletions

View file

@ -198,11 +198,100 @@ pub const Chunk = struct {
}
return raw_quad;
}
fn packMeshFromRawQuads(raw_quads: std.ArrayList(RawQuad), tile_columns: u32, tile_rows: u32) raylib.ChunkMesh {
// Create OpenGL buffers
const triangle_count: i32 = @as(i32, @intCast(raw_quads.items.len)) * 2;
// Create mesh of a chunk. tile_rows and tile_columns are the dimensions of the tiles.png file, in terms of individual tile textures.
pub fn createMesh(chunk: Chunk, tile_rows: u32, tile_columns: u32) !raylib.ChunkMesh {
const arr_size: u32 = @as(u32, @intCast(triangle_count)) * 3 * @sizeOf(f32);
const vertices: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 3)));
const texcoords: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 2)));
const tiletexcoords: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 2)));
const normals: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 3)));
const metadata1_packed: [*]u32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 4)));
const occlusion_sides: [*]u32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 4)));
for (raw_quads.items, 0..) |raw_quad, i| {
if (raw_quad.tile <= 0) continue; // air tile, no texture
const tile = raw_quad.tile;
// Set normals for the quads (same as the triangles.)
for (0..6) |j| {
normals[18 * i + 3 * j + 0] = raw_quad.normal.x;
normals[18 * i + 3 * j + 1] = raw_quad.normal.y;
normals[18 * i + 3 * j + 2] = raw_quad.normal.z;
}
// Find UV coordinates of corresponding tiles.
const left_uv = @as(f32, @floatFromInt(tile % tile_columns)) / @as(f32, @floatFromInt(tile_columns));
const right_uv = @as(f32, @floatFromInt(tile % tile_columns + 1)) / @as(f32, @floatFromInt(tile_columns));
const top_uv = @as(f32, @floatFromInt(tile / tile_columns)) / @as(f32, @floatFromInt(tile_rows));
const bottom_uv = @as(f32, @floatFromInt(tile / tile_columns + 1)) / @as(f32, @floatFromInt(tile_rows));
// Unwrap raw quads vertex coordinates and UV coordinates into OpenGL buffers.
const vertex_corners = .{ raw_quad.top_left, raw_quad.bottom_left, raw_quad.top_right, raw_quad.bottom_right, raw_quad.top_right, raw_quad.bottom_left };
const texcoords_x = .{ left_uv, left_uv, right_uv, right_uv, right_uv, left_uv };
const texcoords_y = .{ top_uv, bottom_uv } ** 3;
const tiletexcoords_x = if(raw_quad.flip_x)
.{raw_quad.width, raw_quad.width, 0.0, 0.0, 0.0, raw_quad.width} else
.{ 0.0, 0.0, raw_quad.width, raw_quad.width, raw_quad.width, 0.0 };
const tiletexcoords_y = if(raw_quad.flip_y) .{ raw_quad.height, 0.0 } ** 3 else .{ 0.0, raw_quad.height } ** 3;
inline for (0..6) |corner_id| {
vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 0] = vertex_corners[corner_id].x;
vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 1] = vertex_corners[corner_id].y;
vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 2] = vertex_corners[corner_id].z;
texcoords[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 0] = texcoords_x[corner_id];
texcoords[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 1] = texcoords_y[corner_id];
tiletexcoords[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 0] = tiletexcoords_x[corner_id];
tiletexcoords[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 1] = tiletexcoords_y[corner_id];
}
// Store metadata into OpenGL buffers.
for (0..6) |j| {
const metadata1 = Metadata1{
.top_left_obscured = raw_quad.top_left_obscured,
.top_right_obscured = raw_quad.top_right_obscured,
.bottom_left_obscured = raw_quad.bottom_left_obscured,
.bottom_right_obscured = raw_quad.bottom_right_obscured,
.quad_height = @intFromFloat(raw_quad.height),
.quad_width = @intFromFloat(raw_quad.width),
};
const metadata1_baked: [4]u32 = @bitCast(metadata1);
for (0..4) |k| {
metadata1_packed[24 * i + 4 * j + k] = metadata1_baked[k];
}
}
// Store ambient occlusion sides into OpenGL buffers.
for (0..6) |j| {
occlusion_sides[24 * i + 4 * j + 0] = raw_quad.left_obscuring_pattern;
occlusion_sides[24 * i + 4 * j + 1] = raw_quad.right_obscuring_pattern;
occlusion_sides[24 * i + 4 * j + 2] = raw_quad.top_obscuring_pattern;
occlusion_sides[24 * i + 4 * j + 3] = raw_quad.bottom_obscuring_pattern;
}
}
// Create mesh using the buffers.
return raylib.ChunkMesh{
.triangleCount = triangle_count,
.vertexCount = triangle_count * 3,
.vertices = vertices,
.texcoords = texcoords,
.tiletexcoords = tiletexcoords,
.normals = normals,
.metadata1 = metadata1_packed,
.occlusion_sides = occlusion_sides,
.vaoId = 0,
.vboId = null,
};
}
fn scanForRawQuads(chunk: Chunk) !std.ArrayList(RawQuad) {
var raw_quads = try std.ArrayList(RawQuad).initCapacity(chunk.a7r, 4096);
defer raw_quads.deinit();
// Begin scanning the chunk for tile surfaces to make raw quads.
inline for (0..3) |dimension| { // Iterate over the 3 dimensions, X, Y and Z.
@ -290,95 +379,15 @@ pub const Chunk = struct {
}
}
}
return raw_quads;
}
// Create OpenGL buffers
const triangle_count: i32 = @as(i32, @intCast(raw_quads.items.len)) * 2;
// Create mesh of a chunk. tile_rows and tile_columns are the dimensions of the tiles.png file, in terms of individual tile textures.
pub fn createMesh(chunk: Chunk, tile_rows: u32, tile_columns: u32) !raylib.ChunkMesh {
var raw_quads = try scanForRawQuads(chunk);
defer raw_quads.deinit();
const arr_size: u32 = @as(u32, @intCast(triangle_count)) * 3 * @sizeOf(f32);
const vertices: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 3)));
const texcoords: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 2)));
const tiletexcoords: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 2)));
const normals: [*]f32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 3)));
const metadata1_packed: [*]u32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 4)));
const occlusion_sides: [*]u32 = @ptrCast(@alignCast(raylib.MemAlloc(arr_size * 4)));
for (raw_quads.items, 0..) |raw_quad, i| {
if (raw_quad.tile <= 0) continue; // air tile, no texture
const tile = raw_quad.tile;
// Set normals for the quads (same as the triangles.)
for (0..6) |j| {
normals[18 * i + 3 * j + 0] = raw_quad.normal.x;
normals[18 * i + 3 * j + 1] = raw_quad.normal.y;
normals[18 * i + 3 * j + 2] = raw_quad.normal.z;
}
// Find UV coordinates of corresponding tiles.
const left_uv = @as(f32, @floatFromInt(tile % tile_columns)) / @as(f32, @floatFromInt(tile_columns));
const right_uv = @as(f32, @floatFromInt(tile % tile_columns + 1)) / @as(f32, @floatFromInt(tile_columns));
const top_uv = @as(f32, @floatFromInt(tile / tile_columns)) / @as(f32, @floatFromInt(tile_rows));
const bottom_uv = @as(f32, @floatFromInt(tile / tile_columns + 1)) / @as(f32, @floatFromInt(tile_rows));
// Unwrap raw quads vertex coordinates and UV coordinates into OpenGL buffers.
const vertex_corners = .{ raw_quad.top_left, raw_quad.bottom_left, raw_quad.top_right, raw_quad.bottom_right, raw_quad.top_right, raw_quad.bottom_left };
const texcoords_x = .{ left_uv, left_uv, right_uv, right_uv, right_uv, left_uv };
const texcoords_y = .{ top_uv, bottom_uv } ** 3;
const tiletexcoords_x = if(raw_quad.flip_x)
.{raw_quad.width, raw_quad.width, 0.0, 0.0, 0.0, raw_quad.width} else
.{ 0.0, 0.0, raw_quad.width, raw_quad.width, raw_quad.width, 0.0 };
const tiletexcoords_y = if(raw_quad.flip_y) .{ raw_quad.height, 0.0 } ** 3 else .{ 0.0, raw_quad.height } ** 3;
inline for (0..6) |corner_id| {
vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 0] = vertex_corners[corner_id].x;
vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 1] = vertex_corners[corner_id].y;
vertices[VERTICES_BLOCK_SIZE * i + corner_id * 3 + 2] = vertex_corners[corner_id].z;
texcoords[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 0] = texcoords_x[corner_id];
texcoords[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 1] = texcoords_y[corner_id];
tiletexcoords[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 0] = tiletexcoords_x[corner_id];
tiletexcoords[TEXCOORDS_BLOCK_SIZE * i + corner_id * 2 + 1] = tiletexcoords_y[corner_id];
}
// Store metadata into OpenGL buffers.
for (0..6) |j| {
const metadata1 = Metadata1{
.top_left_obscured = raw_quad.top_left_obscured,
.top_right_obscured = raw_quad.top_right_obscured,
.bottom_left_obscured = raw_quad.bottom_left_obscured,
.bottom_right_obscured = raw_quad.bottom_right_obscured,
.quad_height = @intFromFloat(raw_quad.height),
.quad_width = @intFromFloat(raw_quad.width),
};
const metadata1_baked: [4]u32 = @bitCast(metadata1);
for (0..4) |k| {
metadata1_packed[24 * i + 4 * j + k] = metadata1_baked[k];
}
}
// Store ambient occlusion sides into OpenGL buffers.
for (0..6) |j| {
occlusion_sides[24 * i + 4 * j + 0] = raw_quad.left_obscuring_pattern;
occlusion_sides[24 * i + 4 * j + 1] = raw_quad.right_obscuring_pattern;
occlusion_sides[24 * i + 4 * j + 2] = raw_quad.top_obscuring_pattern;
occlusion_sides[24 * i + 4 * j + 3] = raw_quad.bottom_obscuring_pattern;
}
}
// Create mesh using the buffers.
var mesh = raylib.ChunkMesh{
.triangleCount = triangle_count,
.vertexCount = triangle_count * 3,
.vertices = vertices,
.texcoords = texcoords,
.tiletexcoords = tiletexcoords,
.normals = normals,
.metadata1 = metadata1_packed,
.occlusion_sides = occlusion_sides,
.vaoId = 0,
.vboId = null,
};
var mesh = packMeshFromRawQuads(raw_quads, tile_columns, tile_rows);
raylib.UploadChunkMesh(@ptrCast(&mesh), false);