mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-15 07:20:09 -04:00
parent
1cca3a5769
commit
781ca89aff
@ -98,6 +98,17 @@ fn extractZFromIndex(index: usize) i32 {
|
||||
return @intCast(index & chunkMask);
|
||||
}
|
||||
|
||||
var memoryPool: std.heap.MemoryPoolAligned(Chunk, @alignOf(Chunk)) = undefined;
|
||||
var memoryPoolMutex: std.Thread.Mutex = .{};
|
||||
|
||||
pub fn init() void {
|
||||
memoryPool = std.heap.MemoryPoolAligned(Chunk, @alignOf(Chunk)).init(main.globalAllocator.allocator);
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
memoryPool.deinit();
|
||||
}
|
||||
|
||||
pub const ChunkPosition = struct {
|
||||
wx: i32,
|
||||
wy: i32,
|
||||
@ -170,7 +181,10 @@ pub const Chunk = struct {
|
||||
widthShift: u5,
|
||||
mutex: std.Thread.Mutex,
|
||||
|
||||
pub fn init(self: *Chunk, pos: ChunkPosition) void {
|
||||
pub fn init(pos: ChunkPosition) *Chunk {
|
||||
memoryPoolMutex.lock();
|
||||
const self = memoryPool.create() catch unreachable;
|
||||
memoryPoolMutex.unlock();
|
||||
std.debug.assert((pos.voxelSize - 1 & pos.voxelSize) == 0);
|
||||
std.debug.assert(@mod(pos.wx, pos.voxelSize) == 0 and @mod(pos.wy, pos.voxelSize) == 0 and @mod(pos.wz, pos.voxelSize) == 0);
|
||||
const voxelSizeShift: u5 = @intCast(std.math.log2_int(u31, pos.voxelSize));
|
||||
@ -182,6 +196,13 @@ pub const Chunk = struct {
|
||||
.widthShift = voxelSizeShift + chunkShift,
|
||||
.mutex = std.Thread.Mutex{},
|
||||
};
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Chunk) void {
|
||||
memoryPoolMutex.lock();
|
||||
memoryPool.destroy(@alignCast(self));
|
||||
memoryPoolMutex.unlock();
|
||||
}
|
||||
|
||||
pub fn setChanged(self: *Chunk) void {
|
||||
|
@ -707,6 +707,9 @@ pub fn main() void {
|
||||
gui.init();
|
||||
defer gui.deinit();
|
||||
|
||||
chunk.init();
|
||||
defer chunk.deinit();
|
||||
|
||||
rotation.init();
|
||||
defer rotation.deinit();
|
||||
|
||||
|
@ -743,8 +743,7 @@ pub const Protocols = struct {
|
||||
std.log.err("Transmission of chunk has invalid size: {}. Input data: {any}, After inflate: {any}", .{_inflatedLen, data, _inflatedData[0.._inflatedLen]});
|
||||
}
|
||||
data = _inflatedData;
|
||||
const ch = main.globalAllocator.create(chunk.Chunk);
|
||||
ch.init(pos);
|
||||
const ch = chunk.Chunk.init(pos);
|
||||
for(&ch.blocks) |*block| {
|
||||
block.* = Block.fromInt(std.mem.readInt(u32, data[0..4], .big));
|
||||
data = data[4..];
|
||||
@ -768,8 +767,7 @@ pub const Protocols = struct {
|
||||
conn.sendImportant(id, data);
|
||||
}
|
||||
fn sendChunkLocally(ch: *chunk.Chunk) void {
|
||||
const chunkCopy = main.globalAllocator.create(chunk.Chunk);
|
||||
chunkCopy.init(ch.pos);
|
||||
const chunkCopy = chunk.Chunk.init(ch.pos);
|
||||
@memcpy(&chunkCopy.blocks, &ch.blocks);
|
||||
renderer.mesh_storage.updateChunkMesh(chunkCopy);
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ pub var quadsDrawn: usize = 0;
|
||||
pub var transparentQuadsDrawn: usize = 0;
|
||||
|
||||
pub fn init() void {
|
||||
lighting.init();
|
||||
shader = Shader.initAndGetUniforms("assets/cubyz/shaders/chunks/chunk_vertex.vs", "assets/cubyz/shaders/chunks/chunk_fragment.fs", &uniforms);
|
||||
transparentShader = Shader.initAndGetUniforms("assets/cubyz/shaders/chunks/chunk_vertex.vs", "assets/cubyz/shaders/chunks/transparent_fragment.fs", &transparentUniforms);
|
||||
|
||||
@ -73,6 +74,7 @@ pub fn init() void {
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
lighting.deinit();
|
||||
shader.deinit();
|
||||
transparentShader.deinit();
|
||||
c.glDeleteVertexArrays(1, &vao);
|
||||
@ -240,12 +242,12 @@ const PrimitiveMesh = struct {
|
||||
const z = (wz >> mesh.chunk.voxelSizeShift) & chunk.chunkMask;
|
||||
const index = chunk.getIndex(x, y, z);
|
||||
return .{
|
||||
mesh.lightingData.*[0].data[index].load(.Unordered),
|
||||
mesh.lightingData.*[1].data[index].load(.Unordered),
|
||||
mesh.lightingData.*[2].data[index].load(.Unordered),
|
||||
mesh.lightingData.*[3].data[index].load(.Unordered),
|
||||
mesh.lightingData.*[4].data[index].load(.Unordered),
|
||||
mesh.lightingData.*[5].data[index].load(.Unordered),
|
||||
mesh.lightingData[0].data[index].load(.Unordered),
|
||||
mesh.lightingData[1].data[index].load(.Unordered),
|
||||
mesh.lightingData[2].data[index].load(.Unordered),
|
||||
mesh.lightingData[3].data[index].load(.Unordered),
|
||||
mesh.lightingData[4].data[index].load(.Unordered),
|
||||
mesh.lightingData[5].data[index].load(.Unordered),
|
||||
};
|
||||
}
|
||||
|
||||
@ -422,7 +424,7 @@ pub const ChunkMesh = struct {
|
||||
pos: chunk.ChunkPosition,
|
||||
size: i32,
|
||||
chunk: *chunk.Chunk,
|
||||
lightingData: *[6]lighting.ChannelChunk,
|
||||
lightingData: [6]*lighting.ChannelChunk,
|
||||
opaqueMesh: PrimitiveMesh,
|
||||
transparentMesh: PrimitiveMesh,
|
||||
lastNeighborsSameLod: [6]?*const ChunkMesh = [_]?*const ChunkMesh{null} ** 6,
|
||||
@ -444,20 +446,20 @@ pub const ChunkMesh = struct {
|
||||
chunkBorders: [6]BoundingRectToNeighborChunk = [1]BoundingRectToNeighborChunk{.{}} ** 6,
|
||||
|
||||
pub fn init(self: *ChunkMesh, pos: chunk.ChunkPosition, ch: *chunk.Chunk) void {
|
||||
const lightingData = main.globalAllocator.create([6]lighting.ChannelChunk);
|
||||
lightingData[0].init(ch, .sun_red);
|
||||
lightingData[1].init(ch, .sun_green);
|
||||
lightingData[2].init(ch, .sun_blue);
|
||||
lightingData[3].init(ch, .red);
|
||||
lightingData[4].init(ch, .green);
|
||||
lightingData[5].init(ch, .blue);
|
||||
self.* = ChunkMesh{
|
||||
.pos = pos,
|
||||
.size = chunk.chunkSize*pos.voxelSize,
|
||||
.opaqueMesh = .{},
|
||||
.transparentMesh = .{},
|
||||
.chunk = ch,
|
||||
.lightingData = lightingData,
|
||||
.lightingData = .{
|
||||
lighting.ChannelChunk.init(ch, .sun_red),
|
||||
lighting.ChannelChunk.init(ch, .sun_green),
|
||||
lighting.ChannelChunk.init(ch, .sun_blue),
|
||||
lighting.ChannelChunk.init(ch, .red),
|
||||
lighting.ChannelChunk.init(ch, .green),
|
||||
lighting.ChannelChunk.init(ch, .blue),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -465,10 +467,12 @@ pub const ChunkMesh = struct {
|
||||
std.debug.assert(self.refCount.load(.Monotonic) == 0);
|
||||
self.opaqueMesh.deinit();
|
||||
self.transparentMesh.deinit();
|
||||
self.chunk.deinit();
|
||||
main.globalAllocator.free(self.currentSorting);
|
||||
main.globalAllocator.free(self.sortingOutputBuffer);
|
||||
main.globalAllocator.destroy(self.chunk);
|
||||
main.globalAllocator.destroy(self.lightingData);
|
||||
for(self.lightingData) |lightingChunk| {
|
||||
lightingChunk.deinit();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn increaseRefCount(self: *ChunkMesh) void {
|
||||
@ -584,7 +588,7 @@ pub const ChunkMesh = struct {
|
||||
}
|
||||
}
|
||||
self.mutex.unlock();
|
||||
for(self.lightingData[3..]) |*lightingData| {
|
||||
for(self.lightingData[3..]) |lightingData| {
|
||||
lightingData.propagateLights(lightEmittingBlocks.items, true);
|
||||
}
|
||||
sunLight: {
|
||||
@ -604,7 +608,7 @@ pub const ChunkMesh = struct {
|
||||
}
|
||||
}
|
||||
}
|
||||
for(self.lightingData[0..3]) |*lightingData| {
|
||||
for(self.lightingData[0..3]) |lightingData| {
|
||||
lightingData.propagateLights(sunStarters[0..index], true);
|
||||
}
|
||||
}
|
||||
@ -728,11 +732,11 @@ pub const ChunkMesh = struct {
|
||||
const oldBlock = self.chunk.blocks[chunk.getIndex(x, y, z)];
|
||||
self.chunk.blocks[chunk.getIndex(x, y, z)] = newBlock;
|
||||
self.mutex.unlock();
|
||||
for(self.lightingData[0..]) |*lightingData| {
|
||||
for(self.lightingData[0..]) |lightingData| {
|
||||
lightingData.propagateLightsDestructive(&.{.{@intCast(x), @intCast(y), @intCast(z)}});
|
||||
}
|
||||
if(newBlock.light() != 0) {
|
||||
for(self.lightingData[3..]) |*lightingData| {
|
||||
for(self.lightingData[3..]) |lightingData| {
|
||||
lightingData.propagateLights(&.{.{@intCast(x), @intCast(y), @intCast(z)}}, false);
|
||||
}
|
||||
}
|
||||
|
@ -31,17 +31,38 @@ const Channel = enum(u8) {
|
||||
}
|
||||
};
|
||||
|
||||
var memoryPool: std.heap.MemoryPool(ChannelChunk) = undefined;
|
||||
var memoryPoolMutex: std.Thread.Mutex = .{};
|
||||
|
||||
pub fn init() void {
|
||||
memoryPool = std.heap.MemoryPool(ChannelChunk).init(main.globalAllocator.allocator);
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
memoryPool.deinit();
|
||||
}
|
||||
|
||||
pub const ChannelChunk = struct {
|
||||
data: [chunk.chunkVolume]Atomic(u8),
|
||||
mutex: std.Thread.Mutex,
|
||||
ch: *chunk.Chunk,
|
||||
channel: Channel,
|
||||
|
||||
pub fn init(self: *ChannelChunk, ch: *chunk.Chunk, channel: Channel) void {
|
||||
pub fn init(ch: *chunk.Chunk, channel: Channel) *ChannelChunk {
|
||||
memoryPoolMutex.lock();
|
||||
const self = memoryPool.create() catch unreachable;
|
||||
memoryPoolMutex.unlock();
|
||||
self.mutex = .{};
|
||||
self.ch = ch;
|
||||
self.channel = channel;
|
||||
@memset(&self.data, Atomic(u8).init(0));
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *ChannelChunk) void {
|
||||
memoryPoolMutex.lock();
|
||||
memoryPool.destroy(self);
|
||||
memoryPoolMutex.unlock();
|
||||
}
|
||||
|
||||
const Entry = struct {
|
||||
@ -235,7 +256,7 @@ pub const ChannelChunk = struct {
|
||||
const otherZ = z+%chunk.Neighbors.relZ[neighbor] & chunk.chunkMask;
|
||||
const neighborMesh = mesh_storage.getNeighborAndIncreaseRefCount(self.ch.pos, self.ch.pos.voxelSize, @intCast(neighbor)) orelse continue;
|
||||
defer neighborMesh.decreaseRefCount();
|
||||
const neighborLightChunk = &neighborMesh.lightingData[@intFromEnum(self.channel)];
|
||||
const neighborLightChunk = neighborMesh.lightingData[@intFromEnum(self.channel)];
|
||||
const index = chunk.getIndex(x, y, z);
|
||||
const neighborIndex = chunk.getIndex(otherX, otherY, otherZ);
|
||||
var value: u8 = neighborLightChunk.data[neighborIndex].load(.Unordered);
|
||||
@ -272,7 +293,7 @@ pub const ChannelChunk = struct {
|
||||
defer if(mesh) |_mesh| _mesh.decreaseRefCount();
|
||||
var entryList = entries.entries;
|
||||
defer entryList.deinit(main.globalAllocator);
|
||||
const channelChunk = if(mesh) |_mesh| &_mesh.lightingData[@intFromEnum(self.channel)] else self;
|
||||
const channelChunk = if(mesh) |_mesh| _mesh.lightingData[@intFromEnum(self.channel)] else self;
|
||||
for(entryList.items) |entry| {
|
||||
const index = chunk.getIndex(entry.x, entry.y, entry.z);
|
||||
const value = channelChunk.data[index].load(.Unordered);
|
||||
|
@ -1022,7 +1022,7 @@ pub const MeshGenerationTask = struct {
|
||||
}
|
||||
|
||||
pub fn clean(self: *MeshGenerationTask) void {
|
||||
main.globalAllocator.destroy(self.mesh);
|
||||
self.mesh.deinit();
|
||||
main.globalAllocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
@ -213,8 +213,7 @@ const ChunkManager = struct {
|
||||
}
|
||||
|
||||
fn chunkInitFunctionForCache(pos: ChunkPosition) *Chunk {
|
||||
const ch = main.globalAllocator.create(Chunk);
|
||||
ch.init(pos);
|
||||
const ch = Chunk.init(pos);
|
||||
ch.generated = true;
|
||||
// TODO: if(!ChunkIO.loadChunkFromFile(world, this)) {
|
||||
const caveMap = terrain.CaveMap.CaveMapView.init(ch);
|
||||
@ -228,7 +227,7 @@ const ChunkManager = struct {
|
||||
}
|
||||
|
||||
fn chunkDeinitFunctionForCache(ch: *Chunk) void {
|
||||
main.globalAllocator.destroy(ch);
|
||||
ch.deinit();
|
||||
// TODO: Store chunk.
|
||||
}
|
||||
/// Generates a normal chunk at a given location, or if possible gets it from the cache.
|
||||
|
Loading…
x
Reference in New Issue
Block a user