NOT WORKING ATM. something with block ids.
This commit is contained in:
@@ -3,7 +3,7 @@ use noise::{Perlin, NoiseFn};
|
|||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
use crate::renderer::Level;
|
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 {
|
pub struct WorldGen {
|
||||||
@@ -25,14 +25,9 @@ impl WorldGen {
|
|||||||
const SCALE: f64 = 150.0;
|
const SCALE: f64 = 150.0;
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
for bx in 0..32 {
|
|
||||||
for bz in 0..32 {
|
|
||||||
|
|
||||||
let mut block_ids = [0_usize; 16];
|
for bx in 0..16 {
|
||||||
for by in 0..2 {
|
for bz in 0..16 {
|
||||||
//TODO consume only nonempty blocks
|
|
||||||
block_ids[by] = level.block_get_id(Point3{x:bx, y:by, z:bz}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
for x in 0..BLOCK_SIZE {
|
for x in 0..BLOCK_SIZE {
|
||||||
for z in 0..BLOCK_SIZE {
|
for z in 0..BLOCK_SIZE {
|
||||||
@@ -53,7 +48,7 @@ impl WorldGen {
|
|||||||
let by = wy / BLOCK_SIZE;
|
let by = wy / BLOCK_SIZE;
|
||||||
let val = if wy == wh-1 { 2 } else { 1 };
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,28 @@
|
|||||||
use std::convert::TryInto;
|
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)]
|
#[derive(Clone)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
|
pub id: usize,
|
||||||
pub data: [u8;BLOCK_LEN]
|
pub data: [u8;BLOCK_LEN]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block {
|
impl Block {
|
||||||
pub fn new() -> Self {
|
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 struct Blocks {
|
||||||
pub blocks: Box<[Block]>,
|
blocks: Box<[Block]>,
|
||||||
pub free_block: usize,
|
free_block: usize,
|
||||||
texture: wgpu::Texture,
|
texture: wgpu::Texture,
|
||||||
pub bind_layout: wgpu::BindGroupLayout,
|
pub bind_layout: wgpu::BindGroupLayout,
|
||||||
pub bind_group: wgpu::BindGroup
|
pub bind_group: wgpu::BindGroup
|
||||||
@@ -84,28 +91,24 @@ impl Blocks {
|
|||||||
|
|
||||||
// Data
|
// Data
|
||||||
let mut blocks = vec![Block::new(); BLOCK_ARR_LEN].into_boxed_slice();
|
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);
|
println!("block buffer size: {} MB", BLOCK_TEX_LEN as f32 / 1024.0 / 1024.0);
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
Self { blocks, texture, bind_layout, bind_group, free_block: 0 }
|
Self { blocks, texture, bind_layout, bind_group, free_block: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
pub fn write_id(&mut self, queue: &wgpu::Queue, block_id: usize) {
|
||||||
Write block data to gpu, should be called to apply changes
|
let block = self.get(block_id).unwrap();
|
||||||
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 };
|
|
||||||
|
|
||||||
let y = (block%BLOCK_TEX_SIZE * BLOCK_SIZE) as u32;
|
// Calculate block position in texture
|
||||||
let z = (block/BLOCK_TEX_SIZE * BLOCK_SIZE) as u32;
|
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_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(
|
queue.write_texture(
|
||||||
wgpu::TextureCopyView { texture: &self.texture, mip_level: 0, origin: block_origin },
|
wgpu::TextureCopyView { texture: &self.texture, mip_level: 0, origin: block_origin },
|
||||||
&block_bytes,
|
&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
|
* Allocates new block
|
||||||
* Later: reusing old blocks
|
|
||||||
*/
|
*/
|
||||||
pub fn next_block(&mut self, consume: bool) -> usize {
|
pub fn alloc(&mut self) -> &mut Block {
|
||||||
if self.free_block >= self.blocks.len() {
|
// Make sure we still have some free blocks
|
||||||
panic!("No more free blocks! we should consider reusing 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; }
|
* Gets block with id
|
||||||
next
|
*/
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@ pub use nodes::Nodes;
|
|||||||
|
|
||||||
mod blocks;
|
mod blocks;
|
||||||
pub use blocks::Blocks;
|
pub use blocks::Blocks;
|
||||||
|
pub use blocks::Block;
|
||||||
|
|
||||||
mod uniform;
|
mod uniform;
|
||||||
pub use uniform::Uniform;
|
pub use uniform::Uniform;
|
||||||
|
|||||||
+13
-40
@@ -3,56 +3,29 @@ use crate::renderer::{Renderer, buffers};
|
|||||||
|
|
||||||
|
|
||||||
pub trait Level {
|
pub trait Level {
|
||||||
fn set_voxel(&mut self, x: usize, y: usize, z:usize, value: u8);
|
fn block_get(&mut self, block_pos: Point3<usize>) -> &mut buffers::Block;
|
||||||
fn block_set_voxel(&mut self, brick_id:usize, x: usize, y: usize, z:usize, value: u8);
|
fn block_dirty(&mut self, block: &buffers::Block);
|
||||||
fn block_get_id(&mut self, pos: Point3<usize>, apply: bool) -> usize;
|
|
||||||
fn block_mark_changed(&mut self, brick_id:usize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Level for Renderer {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
fn block_get(&mut self, block_pos: Point3<usize>) -> &mut buffers::Block{
|
||||||
* 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 {
|
|
||||||
// Get node
|
// Get node
|
||||||
let node_idx = pos.x + buffers::NODE_TEX_SIZE * (pos.y + buffers::NODE_TEX_SIZE * pos.z);
|
let node_idx = block_pos.x + buffers::NODE_TEX_SIZE * (block_pos.y + buffers::NODE_TEX_SIZE * block_pos.z);
|
||||||
let mut node_value = self.buffers.node_buffer.nodes[node_idx];
|
let node_value = self.buffers.node_buffer.nodes[node_idx];
|
||||||
|
|
||||||
// Use new brick if neccesary
|
// Allocate new block
|
||||||
if node_value == 0 {
|
if node_value == 0 {
|
||||||
node_value = self.buffers.brick_buffer.next_block(apply) as u32;
|
let block = self.buffers.brick_buffer.alloc();
|
||||||
if apply { self.buffers.node_buffer.nodes[node_idx] = node_value; }
|
self.buffers.node_buffer.nodes[node_idx] = block.id as u32;
|
||||||
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get brick id from node value
|
// Return existing block
|
||||||
let brick_id = (node_value - 1) as usize;
|
self.buffers.brick_buffer.get(node_idx).unwrap()
|
||||||
if apply { self.block_mark_changed(brick_id); }
|
|
||||||
brick_id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
fn block_dirty(&mut self, block: &buffers::Block) {
|
||||||
* Marks brick as changed
|
self.changed_bricks.push(block.id);
|
||||||
*/
|
|
||||||
fn block_mark_changed(&mut self, brick_id:usize) {
|
|
||||||
if !self.changed_bricks.contains(&brick_id) {
|
|
||||||
self.changed_bricks.push(brick_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-6
@@ -120,14 +120,14 @@ impl Renderer {
|
|||||||
// Update changed nodes
|
// Update changed nodes
|
||||||
if self.changed_bricks.len() > 0 {
|
if self.changed_bricks.len() > 0 {
|
||||||
self.buffers.node_buffer.write(&self.queue);
|
self.buffers.node_buffer.write(&self.queue);
|
||||||
for node in &self.changed_bricks {
|
for block_id in &self.changed_bricks {
|
||||||
self.buffers.brick_buffer.write(&self.queue, *node);
|
self.buffers.brick_buffer.write_id(&self.queue, *block_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let used = self.buffers.brick_buffer.next_block(false);
|
// let used = self.buffers.brick_buffer.next_block(false);
|
||||||
let total = buffers::BLOCK_TEX_SIZE * buffers::BLOCK_TEX_SIZE;
|
// let total = buffers::BLOCK_TEX_SIZE * buffers::BLOCK_TEX_SIZE;
|
||||||
let changed = self.changed_bricks.len();
|
// let changed = self.changed_bricks.len();
|
||||||
println!("Used: {}/{} Changed: {}", used, total, changed);
|
// println!("Used: {}/{} Changed: {}", used, total, changed);
|
||||||
|
|
||||||
self.changed_bricks.clear();
|
self.changed_bricks.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user