NOT WORKING ATM. something with block ids.

This commit is contained in:
Piotrek
2021-04-28 21:21:29 +02:00
parent 600fe689b7
commit 719b6f8f26
5 changed files with 84 additions and 83 deletions
+4 -9
View File
@@ -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);
}
}
}
+57 -25
View File
@@ -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<usize>, 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 {
);
}
// /*
// 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();
// // 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
// );
// }
/*
* Get id of next free block
* Later: reusing old blocks
* Allocates new block
*/
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...");
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]
}
let next = self.free_block + 1;
if consume { self.free_block = next; }
next
/*
* 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
}
}
+1
View File
@@ -20,6 +20,7 @@ pub use nodes::Nodes;
mod blocks;
pub use blocks::Blocks;
pub use blocks::Block;
mod uniform;
pub use uniform::Uniform;
+13 -40
View File
@@ -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<usize>, apply: bool) -> usize;
fn block_mark_changed(&mut self, brick_id:usize);
fn block_get(&mut self, block_pos: Point3<usize>) -> &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<usize>, apply: bool) -> usize {
fn block_get(&mut self, block_pos: Point3<usize>) -> &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);
}
}
+6 -6
View File
@@ -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();
}