From 3718c2145ea86f81b7696c10300253776a108ec4 Mon Sep 17 00:00:00 2001 From: Piotrek Date: Tue, 18 May 2021 20:53:26 +0200 Subject: [PATCH] fixed bug where world offset was applied to camera position delayed 1 frame --- src/game/mod.rs | 4 +-- src/game/world/mod.rs | 8 ------ src/renderer/buffers/nodes.rs | 48 ++++++++++++++++++----------------- src/renderer/mod.rs | 13 +++++----- 4 files changed, 33 insertions(+), 40 deletions(-) diff --git a/src/game/mod.rs b/src/game/mod.rs index 81880ca..d465bd6 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -53,7 +53,7 @@ impl Game { fn load_chunks(&mut self, renderer: &mut impl RendererView, chunk_pos: Vector3) { // Wait for previous chunks to be loaded before loading new ones - //if !self.world.is_busy() { + if !renderer.is_busy() { if self.prev_chunk_pos == None { self.prev_chunk_pos = Some(chunk_pos); } let prev_chunk_pos = self.prev_chunk_pos.unwrap(); let mut dir = chunk_pos - prev_chunk_pos; @@ -77,7 +77,7 @@ impl Game { } self.prev_chunk_pos = Some(prev_chunk_pos+dir); - //} + } } pub fn update(&mut self, delta: f32, renderer: &mut impl RendererView) { diff --git a/src/game/world/mod.rs b/src/game/world/mod.rs index ae0b251..7aae7a0 100644 --- a/src/game/world/mod.rs +++ b/src/game/world/mod.rs @@ -22,7 +22,6 @@ pub struct World { data: WorldData, loader: ChunkLoader, chunks: HashMap, WorldChunk>, - busy: u32 } impl World { @@ -32,24 +31,18 @@ impl World { data: WorldData { name: name.clone(), ..Default::default() }, loader: ChunkLoader::new(name.clone()), chunks: HashMap::new(), - busy: 0, }; instance.load_metadata(); instance.save_all(); instance } - pub fn is_busy(&self) -> bool { - self.busy > 0 - } - /* * Receives loaded chunks from ChunkLoader */ pub fn update(&mut self) { for (pos, chunk) in self.loader.receive() { self.chunks.insert(pos, chunk); - self.busy -= 1; } } @@ -61,7 +54,6 @@ impl World { chunk.dirty = true; } else { self.loader.load(pos); - self.busy += 1; } } diff --git a/src/renderer/buffers/nodes.rs b/src/renderer/buffers/nodes.rs index 130c51b..d204e0b 100644 --- a/src/renderer/buffers/nodes.rs +++ b/src/renderer/buffers/nodes.rs @@ -17,8 +17,8 @@ pub struct Nodes { buffer: Box<[u32]>, offset: Vector3, dirty: bool, - busy: bool, - queue: Vec>, + shift: Option>, + working: bool, channel: (Sender, Receiver) } @@ -29,8 +29,9 @@ impl Nodes { buffer: vec![0_u32; NODE_TEX_SIZE_QB].into_boxed_slice(), offset: Vector3{x:0,y:0,z:0}, dirty: false, - busy: false, - queue: Vec::new(), + + shift: None, + working: false, channel: mpsc::channel() } } @@ -44,7 +45,7 @@ impl Nodes { } pub fn is_busy(&self) -> bool { - self.busy + self.shift != None } pub fn set_node(&mut self, index: usize, value: u32) { @@ -53,31 +54,24 @@ impl Nodes { } pub fn shift(&mut self, offset: &Vector3) { - self.queue.push(*offset); + if self.shift == None { + self.shift = Some(*offset); + } else { + println!("Tried to shift while another shifin was in progress"); + } } pub fn update(&mut self, queue: &wgpu::Queue, texture: &wgpu::Texture) { - // Receive work - while let Ok(result) = self.channel.1.try_recv() { - self.offset += result.0; - self.buffer = result.1; - self.busy = false; - self.dirty = true; - } - // Check if there is some more work - if !self.busy { - if let Some(offset) = self.queue.pop() { - self.busy = true; - self.dirty = false; + if !self.working { + if let Some(offset) = self.shift { let source = self.buffer.clone(); let tx = self.channel.0.clone(); - + self.working = true; + // Spawn worker thread::spawn(move || { - println!("shift worker start: {:?}", offset); - let size = NODE_TEX_SIZE as i32; let mut target = vec![0_u32; NODE_TEX_SIZE_QB].into_boxed_slice(); let (ox, oy, oz) = (offset.x, offset.y, offset.z); @@ -92,14 +86,22 @@ impl Nodes { } } } - + // Send result tx.send((offset, target)).unwrap(); - println!("shift worker done: {:?}", offset); }); } } + // Receive work + while let Ok(result) = self.channel.1.try_recv() { + self.offset += result.0; + self.buffer = result.1; + self.shift = None; + self.dirty = true; + self.working = false; + } + if self.dirty { self.dirty = false; diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 2c9a234..a2d9243 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -111,7 +111,12 @@ impl Renderer { * Actually renders the frame */ pub fn render(&mut self) -> Result<(), wgpu::SwapChainError> { - + + // Update content + let timer = Instant::now(); + self.buffers.content.update(&self.queue); + self.ui.set_text("Performance", 1, format!("Update content: {}ms", timer.elapsed().as_micros() as f64 / 1000.0)); + // Update uniform buffer let off = self.buffers.content.get_world_offset(); let half = (buffers::nodes::NODE_TEX_SIZE / 2) as i32; @@ -120,12 +125,6 @@ impl Renderer { self.buffers.uniforms.values.update(&self.camera, cam_offset, self.start.elapsed().as_secs_f32()); self.queue.write_buffer(&self.buffers.uniforms.buffer, 0, bytemuck::cast_slice(&[self.buffers.uniforms.values])); - - // Update content - let timer = Instant::now(); - self.buffers.content.update(&self.queue); - self.ui.set_text("Performance", 1, format!("Update content: {}ms", timer.elapsed().as_micros() as f64 / 1000.0)); - // Get next frame to render to let timer = Instant::now(); let frame = self.swapchain.get_current_frame()?.output;