refactor: put chunk graphics resources in a single struct

This commit is contained in:
catangent 2025-08-28 20:38:18 +01:00
parent c029f40bc7
commit df4ae0a20c
4 changed files with 5110 additions and 19 deletions

5069
out.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -129,11 +129,20 @@ pub fn main() !void {
var global_graphics_mutex: std.Thread.Mutex = undefined;
var world_state: WorldState = WorldState.init(&thread_pool, allocator);
const chunk_graphics_resources: chunks.ChunkGraphicsResources = .{
.tile_rows = tile_rows,
.tile_columns = tile_columns,
.texture = texture,
.ambient_occlusion_texture = ambient_occlusion_texture,
.shader = shader,
.global_graphics_mutex = &global_graphics_mutex
};
var world_state: WorldState = WorldState.init(&thread_pool, allocator, chunk_graphics_resources);
defer world_state.deinit();
for (0..50) |x| for (0..50) |z| {
try world_state.queueLoadChunk(.{@intCast(x), 0, @intCast(z)}, tile_rows, tile_columns, texture, ambient_occlusion_texture, shader, &global_graphics_mutex);
for (0..10) |x| for (0..10) |z| {
try world_state.queueLoadChunk(.{@intCast(x), 0, @intCast(z)});
};
while (!raylib.WindowShouldClose()) {

View file

@ -54,6 +54,16 @@ comptime {
}
}
pub const ChunkGraphicsResources = struct {
tile_rows: u32,
tile_columns: u32,
texture: raylib.Texture,
ambient_occlusion_texture: raylib.Texture,
shader: raylib.Shader,
global_graphics_mutex: *std.Thread.Mutex
};
pub const Chunk = struct {
tiles: []u32,
allocator: Allocator,

View file

@ -5,17 +5,17 @@ const AutoHashMap = std.AutoHashMap;
const ArrayList = std.ArrayList;
const Chunk = @import("chunk.zig").Chunk;
const ChunkGraphicsResources = @import("chunk.zig").ChunkGraphicsResources;
const chunk_generators = @import("chunk_generators.zig");
const raylib_helper = @import("../lib_helpers/raylib_helper.zig");
const raylib = raylib_helper.raylib;
pub const WorldStateError = error{
ChunkNotGeneratedError,
ChunkNotGeneratedError,
};
pub const ChunkEntry = struct {
mutex: Thread.Mutex = .{},
chunk: ?Chunk = null,
model: ?raylib.ChunkModel = null,
position: @Vector(3, i64),
@ -28,12 +28,14 @@ pub const WorldState = struct {
// TODO: we can do better than a hashmap and a mutex
chunks: AutoHashMap(@Vector(3, i64), *ChunkEntry) = undefined,
chunks_access_mutex: Thread.Mutex = .{},
chunk_graphics_resources: ChunkGraphicsResources = undefined,
pub fn init(global_pool: *Thread.Pool, allocator: Allocator) WorldState {
pub fn init(global_pool: *Thread.Pool, allocator: Allocator, chunk_graphics_resources: ChunkGraphicsResources) WorldState {
var world_state: WorldState = undefined;
world_state.pool = global_pool;
world_state.allocator = allocator;
world_state.chunks = AutoHashMap(@Vector(3, i64), *ChunkEntry).init(allocator);
world_state.chunk_graphics_resources = chunk_graphics_resources;
return world_state;
}
@ -52,13 +54,13 @@ pub const WorldState = struct {
self.* = undefined;
}
pub fn queueLoadChunk(self: *WorldState, pos: @Vector(3, i64), tile_rows: u32, tile_columns: u32, texture: raylib.Texture, ambient_occlusion_texture: raylib.Texture, shader: raylib.Shader, global_graphics_mutex: *Thread.Mutex) !void {
try self.pool.spawn(completeChunk, .{self, pos, tile_rows, tile_columns, texture, ambient_occlusion_texture, shader, global_graphics_mutex});
pub fn queueLoadChunk(self: *WorldState, pos: @Vector(3, i64)) !void {
try self.pool.spawn(completeChunk, .{self, pos});
}
pub fn completeChunk(self: *WorldState, pos: @Vector(3, i64), tile_rows: u32, tile_columns: u32, texture: raylib.Texture, ambient_occlusion_texture: raylib.Texture, shader: raylib.Shader, global_graphics_mutex: *Thread.Mutex) void {
pub fn completeChunk(self: *WorldState, pos: @Vector(3, i64)) void {
_ = generateChunk(self, pos) catch |err| std.debug.print("error while generating chunk: {}", .{err});
_ = generateChunkModel(self, pos, tile_rows, tile_columns, texture, ambient_occlusion_texture, shader, global_graphics_mutex) catch |err| std.debug.print("error while generating chunk model: {}", .{err});
_ = generateChunkModel(self, pos) catch |err| std.debug.print("error while generating chunk model: {}", .{err});
}
pub fn generateChunk(self: *WorldState, pos: @Vector(3, i64)) !Chunk {
@ -71,7 +73,8 @@ pub const WorldState = struct {
return chunk;
}
pub fn generateChunkModel(self: *WorldState, pos: @Vector(3, i64), tile_rows: u32, tile_columns: u32, texture: raylib.Texture, ambient_occlusion_texture: raylib.Texture, shader: raylib.Shader, global_graphics_mutex: *Thread.Mutex) !raylib.ChunkModel {
pub fn generateChunkModel(self: *WorldState, pos: @Vector(3, i64)) !raylib.ChunkModel {
const resources = self.chunk_graphics_resources;
self.chunks_access_mutex.lock();
const chunk_entry = blk: {
const result = try self.chunks.getOrPut(pos);
@ -87,22 +90,22 @@ pub const WorldState = struct {
const chunk = chunk_entry.chunk;
if(chunk == null) return WorldStateError.ChunkNotGeneratedError;
var mesh = try chunk.?.createMesh(tile_rows, tile_columns);
var mesh = try chunk.?.createMesh(resources.tile_rows, resources.tile_columns);
const model = blk: {
global_graphics_mutex.lock();
defer global_graphics_mutex.unlock();
resources.global_graphics_mutex.lock();
defer resources.global_graphics_mutex.unlock();
raylib.MakeContextCurrent();
defer raylib.DropContextCurrent();
raylib.UploadChunkMesh(@ptrCast(&mesh), false);
const model = raylib.LoadChunkModelFromMesh(mesh);
model.materials[0].maps[raylib.MATERIAL_MAP_DIFFUSE].texture = texture;
model.materials[0].shader = shader;
model.materials[0].maps[raylib.MATERIAL_MAP_DIFFUSE].texture = resources.texture;
model.materials[0].shader = resources.shader;
model.materials[0].shader.locs[raylib.SHADER_LOC_MAP_DIFFUSE+1] = raylib.GetShaderLocation(shader, "occlusionMap");
raylib.SetShaderValueTexture(shader, model.materials[0].shader.locs[raylib.SHADER_LOC_MAP_DIFFUSE+1], ambient_occlusion_texture);
model.materials[0].maps[raylib.MATERIAL_MAP_DIFFUSE+1].texture = ambient_occlusion_texture;
model.materials[0].shader.locs[raylib.SHADER_LOC_MAP_DIFFUSE+1] = raylib.GetShaderLocation(resources.shader, "occlusionMap");
raylib.SetShaderValueTexture(resources.shader, model.materials[0].shader.locs[raylib.SHADER_LOC_MAP_DIFFUSE+1], resources.ambient_occlusion_texture);
model.materials[0].maps[raylib.MATERIAL_MAP_DIFFUSE+1].texture = resources.ambient_occlusion_texture;
break :blk model;
};
chunk_entry.model = model;