refactor: put chunk graphics resources in a single struct
This commit is contained in:
parent
c029f40bc7
commit
df4ae0a20c
4 changed files with 5110 additions and 19 deletions
15
src/main.zig
15
src/main.zig
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue