From 719b6f8f26e94aef1e4bb54c31ab337634834d26 Mon Sep 17 00:00:00 2001 From: Piotrek Date: Wed, 28 Apr 2021 21:21:29 +0200 Subject: [PATCH] NOT WORKING ATM. something with block ids. --- src/app/world_gen.rs | 13 ++--- src/renderer/buffers/blocks.rs | 88 +++++++++++++++++++++++----------- src/renderer/buffers/mod.rs | 1 + src/renderer/level.rs | 53 +++++--------------- src/renderer/mod.rs | 12 ++--- 5 files changed, 84 insertions(+), 83 deletions(-) diff --git a/src/app/world_gen.rs b/src/app/world_gen.rs index 4f993af..e681d44 100644 --- a/src/app/world_gen.rs +++ b/src/app/world_gen.rs @@ -3,7 +3,7 @@ use noise::{Perlin, NoiseFn}; use rand::Rng; use crate::renderer::Level; -use crate::renderer::buffers::{BLOCK_SIZE, NODE_TEX_SIZE}; +use crate::renderer::buffers::{BLOCK_SIZE, NODE_TEX_SIZE, Block}; pub struct WorldGen { @@ -25,14 +25,9 @@ impl WorldGen { const SCALE: f64 = 150.0; let mut rng = rand::thread_rng(); - for bx in 0..32 { - for bz in 0..32 { - let mut block_ids = [0_usize; 16]; - for by in 0..2 { - //TODO consume only nonempty blocks - block_ids[by] = level.block_get_id(Point3{x:bx, y:by, z:bz}, true); - } + for bx in 0..16 { + for bz in 0..16 { for x in 0..BLOCK_SIZE { for z in 0..BLOCK_SIZE { @@ -53,7 +48,7 @@ impl WorldGen { let by = wy / BLOCK_SIZE; let val = if wy == wh-1 { 2 } else { 1 }; - level.block_set_voxel(block_ids[by], x, y, z, val); + level.block_get(Point3{x:bx, y:by, z:bz}).set(Point3{x, y, z}, val); } } } diff --git a/src/renderer/buffers/blocks.rs b/src/renderer/buffers/blocks.rs index 45eca8a..5a6cbe2 100644 --- a/src/renderer/buffers/blocks.rs +++ b/src/renderer/buffers/blocks.rs @@ -1,21 +1,28 @@ use std::convert::TryInto; -use crate::renderer::buffers::{BLOCK_SIZE, BLOCK_TEX_SIZE, BLOCK_TEX_LEN, BLOCK_LEN, BLOCK_ARR_LEN}; +use cgmath::Point3; +use crate::renderer::{buffers, buffers::{BLOCK_SIZE, BLOCK_TEX_SIZE, BLOCK_TEX_LEN, BLOCK_LEN, BLOCK_ARR_LEN}}; + #[derive(Clone)] pub struct Block { + pub id: usize, pub data: [u8;BLOCK_LEN] } impl Block { pub fn new() -> Self { - Self { data: [0_u8;BLOCK_LEN] } + Self { id: 0, data: [0_u8;BLOCK_LEN] } + } + + pub fn set(&mut self, voxel_pos: Point3, value: u8) { + self.data[voxel_pos.x + buffers::BLOCK_SIZE * (voxel_pos.y + buffers::BLOCK_SIZE * voxel_pos.z)] = value; } } pub struct Blocks { - pub blocks: Box<[Block]>, - pub free_block: usize, + blocks: Box<[Block]>, + free_block: usize, texture: wgpu::Texture, pub bind_layout: wgpu::BindGroupLayout, pub bind_group: wgpu::BindGroup @@ -84,28 +91,24 @@ impl Blocks { // Data let mut blocks = vec![Block::new(); BLOCK_ARR_LEN].into_boxed_slice(); - blocks[0].data[0] = 1; - + for (i, b) in blocks.iter_mut().enumerate() { b.id = i; } println!("block buffer size: {} MB", BLOCK_TEX_LEN as f32 / 1024.0 / 1024.0); // Done Self { blocks, texture, bind_layout, bind_group, free_block: 0 } } - /* - Write block data to gpu, should be called to apply changes - offset: block index to copy - */ - pub fn write(&mut self, queue: &wgpu::Queue, block: usize) { - // Get first block - let block_bytes : [u8;BLOCK_LEN] = self.blocks[block].data.try_into().unwrap(); - let block_size = wgpu::Extent3d{ width: BLOCK_SIZE as u32, height: BLOCK_SIZE as u32, depth: BLOCK_SIZE as u32 }; + pub fn write_id(&mut self, queue: &wgpu::Queue, block_id: usize) { + let block = self.get(block_id).unwrap(); - let y = (block%BLOCK_TEX_SIZE * BLOCK_SIZE) as u32; - let z = (block/BLOCK_TEX_SIZE * BLOCK_SIZE) as u32; + // Calculate block position in texture + let y = (block.id%BLOCK_TEX_SIZE * BLOCK_SIZE) as u32; + let z = (block.id/BLOCK_TEX_SIZE * BLOCK_SIZE) as u32; let block_origin = wgpu::Origin3d{ x:0, y, z }; + let block_size = wgpu::Extent3d{ width: BLOCK_SIZE as u32, height: BLOCK_SIZE as u32, depth: BLOCK_SIZE as u32 }; + let block_bytes : [u8;BLOCK_LEN] = block.data.try_into().unwrap(); - // Write + // Write to texture queue.write_texture( wgpu::TextureCopyView { texture: &self.texture, mip_level: 0, origin: block_origin }, &block_bytes, @@ -114,17 +117,46 @@ impl Blocks { ); } - /* - * Get id of next free block - * Later: reusing old blocks - */ - pub fn next_block(&mut self, consume: bool) -> usize { - if self.free_block >= self.blocks.len() { - panic!("No more free blocks! we should consider reusing blocks..."); - } + // /* + // Write block data to gpu, should be called to apply changes + // */ + // pub fn write(&self, queue: &wgpu::Queue, block: &Block) { + // // Calculate block position in texture + // let y = (block.id%BLOCK_TEX_SIZE * BLOCK_SIZE) as u32; + // let z = (block.id/BLOCK_TEX_SIZE * BLOCK_SIZE) as u32; + // let block_origin = wgpu::Origin3d{ x:0, y, z }; + // let block_size = wgpu::Extent3d{ width: BLOCK_SIZE as u32, height: BLOCK_SIZE as u32, depth: BLOCK_SIZE as u32 }; + // let block_bytes : [u8;BLOCK_LEN] = block.data.try_into().unwrap(); - let next = self.free_block + 1; - if consume { self.free_block = next; } - next + // // Write to texture + // queue.write_texture( + // wgpu::TextureCopyView { texture: &self.texture, mip_level: 0, origin: block_origin }, + // &block_bytes, + // wgpu::TextureDataLayout { offset: 0, bytes_per_row: block_size.width, rows_per_image: block_size.height }, + // block_size + // ); + // } + + /* + * Allocates new block + */ + pub fn alloc(&mut self) -> &mut Block { + // Make sure we still have some free blocks + if self.free_block >= self.blocks.len() { panic!("No more free blocks! we should consider reusing blocks..."); } + + self.free_block += 1; + &mut self.blocks[self.free_block - 1] + } + + /* + * Gets block with id + */ + pub fn get(&mut self, id: usize) -> Option<&mut Block> { + for b in self.blocks.iter_mut() { + if b.id == id { + return Some(b); + } + } + None } } \ No newline at end of file diff --git a/src/renderer/buffers/mod.rs b/src/renderer/buffers/mod.rs index 8c99b5a..67716a9 100644 --- a/src/renderer/buffers/mod.rs +++ b/src/renderer/buffers/mod.rs @@ -20,6 +20,7 @@ pub use nodes::Nodes; mod blocks; pub use blocks::Blocks; +pub use blocks::Block; mod uniform; pub use uniform::Uniform; diff --git a/src/renderer/level.rs b/src/renderer/level.rs index 950e7f3..82225ce 100644 --- a/src/renderer/level.rs +++ b/src/renderer/level.rs @@ -3,56 +3,29 @@ use crate::renderer::{Renderer, buffers}; pub trait Level { - fn set_voxel(&mut self, x: usize, y: usize, z:usize, value: u8); - fn block_set_voxel(&mut self, brick_id:usize, x: usize, y: usize, z:usize, value: u8); - fn block_get_id(&mut self, pos: Point3, apply: bool) -> usize; - fn block_mark_changed(&mut self, brick_id:usize); + fn block_get(&mut self, block_pos: Point3) -> &mut buffers::Block; + fn block_dirty(&mut self, block: &buffers::Block); } impl Level for Renderer { - /* - * Create or update brick at given location - */ - #[allow(dead_code)] - fn set_voxel(&mut self, x: usize, y: usize, z:usize, value: u8) { - let brick_id = self.block_get_id(Point3{x:x/32, y:y/32, z:z/32}, true); - self.block_set_voxel(brick_id, x%32, y%32, z%32, value); - } - /* - * Create or update brick at given location - */ - fn block_set_voxel(&mut self, brick_id:usize, x: usize, y: usize, z:usize, value: u8) { - let voxel_id = x + buffers::BLOCK_SIZE * (y + buffers::BLOCK_SIZE * z); - self.buffers.brick_buffer.blocks[brick_id].data[voxel_id] = value; - } - - /* - * Gets brick id - */ - fn block_get_id(&mut self, pos: Point3, apply: bool) -> usize { + fn block_get(&mut self, block_pos: Point3) -> &mut buffers::Block{ // Get node - let node_idx = pos.x + buffers::NODE_TEX_SIZE * (pos.y + buffers::NODE_TEX_SIZE * pos.z); - let mut node_value = self.buffers.node_buffer.nodes[node_idx]; + let node_idx = block_pos.x + buffers::NODE_TEX_SIZE * (block_pos.y + buffers::NODE_TEX_SIZE * block_pos.z); + let node_value = self.buffers.node_buffer.nodes[node_idx]; - // Use new brick if neccesary + // Allocate new block if node_value == 0 { - node_value = self.buffers.brick_buffer.next_block(apply) as u32; - if apply { self.buffers.node_buffer.nodes[node_idx] = node_value; } + let block = self.buffers.brick_buffer.alloc(); + self.buffers.node_buffer.nodes[node_idx] = block.id as u32; + return block; } - // Get brick id from node value - let brick_id = (node_value - 1) as usize; - if apply { self.block_mark_changed(brick_id); } - brick_id + // Return existing block + self.buffers.brick_buffer.get(node_idx).unwrap() } - /* - * Marks brick as changed - */ - fn block_mark_changed(&mut self, brick_id:usize) { - if !self.changed_bricks.contains(&brick_id) { - self.changed_bricks.push(brick_id); - } + fn block_dirty(&mut self, block: &buffers::Block) { + self.changed_bricks.push(block.id); } } \ No newline at end of file diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 2d34a4b..44339b7 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -120,14 +120,14 @@ impl Renderer { // Update changed nodes if self.changed_bricks.len() > 0 { self.buffers.node_buffer.write(&self.queue); - for node in &self.changed_bricks { - self.buffers.brick_buffer.write(&self.queue, *node); + for block_id in &self.changed_bricks { + self.buffers.brick_buffer.write_id(&self.queue, *block_id); } - let used = self.buffers.brick_buffer.next_block(false); - let total = buffers::BLOCK_TEX_SIZE * buffers::BLOCK_TEX_SIZE; - let changed = self.changed_bricks.len(); - println!("Used: {}/{} Changed: {}", used, total, changed); + // let used = self.buffers.brick_buffer.next_block(false); + // let total = buffers::BLOCK_TEX_SIZE * buffers::BLOCK_TEX_SIZE; + // let changed = self.changed_bricks.len(); + // println!("Used: {}/{} Changed: {}", used, total, changed); self.changed_bricks.clear(); }