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