fixed bug where world offset was applied to camera position delayed 1 frame

This commit is contained in:
Piotrek
2021-05-18 20:53:26 +02:00
parent 10182730a5
commit 3718c2145e
4 changed files with 33 additions and 40 deletions
+2 -2
View File
@@ -53,7 +53,7 @@ impl Game {
fn load_chunks(&mut self, renderer: &mut impl RendererView, chunk_pos: Vector3<i32>) { fn load_chunks(&mut self, renderer: &mut impl RendererView, chunk_pos: Vector3<i32>) {
// Wait for previous chunks to be loaded before loading new ones // 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); } if self.prev_chunk_pos == None { self.prev_chunk_pos = Some(chunk_pos); }
let prev_chunk_pos = self.prev_chunk_pos.unwrap(); let prev_chunk_pos = self.prev_chunk_pos.unwrap();
let mut dir = chunk_pos - prev_chunk_pos; let mut dir = chunk_pos - prev_chunk_pos;
@@ -77,7 +77,7 @@ impl Game {
} }
self.prev_chunk_pos = Some(prev_chunk_pos+dir); self.prev_chunk_pos = Some(prev_chunk_pos+dir);
//} }
} }
pub fn update(&mut self, delta: f32, renderer: &mut impl RendererView) { pub fn update(&mut self, delta: f32, renderer: &mut impl RendererView) {
-8
View File
@@ -22,7 +22,6 @@ pub struct World {
data: WorldData, data: WorldData,
loader: ChunkLoader, loader: ChunkLoader,
chunks: HashMap<Vector3<i32>, WorldChunk>, chunks: HashMap<Vector3<i32>, WorldChunk>,
busy: u32
} }
impl World { impl World {
@@ -32,24 +31,18 @@ impl World {
data: WorldData { name: name.clone(), ..Default::default() }, data: WorldData { name: name.clone(), ..Default::default() },
loader: ChunkLoader::new(name.clone()), loader: ChunkLoader::new(name.clone()),
chunks: HashMap::new(), chunks: HashMap::new(),
busy: 0,
}; };
instance.load_metadata(); instance.load_metadata();
instance.save_all(); instance.save_all();
instance instance
} }
pub fn is_busy(&self) -> bool {
self.busy > 0
}
/* /*
* Receives loaded chunks from ChunkLoader * Receives loaded chunks from ChunkLoader
*/ */
pub fn update(&mut self) { pub fn update(&mut self) {
for (pos, chunk) in self.loader.receive() { for (pos, chunk) in self.loader.receive() {
self.chunks.insert(pos, chunk); self.chunks.insert(pos, chunk);
self.busy -= 1;
} }
} }
@@ -61,7 +54,6 @@ impl World {
chunk.dirty = true; chunk.dirty = true;
} else { } else {
self.loader.load(pos); self.loader.load(pos);
self.busy += 1;
} }
} }
+23 -21
View File
@@ -17,8 +17,8 @@ pub struct Nodes {
buffer: Box<[u32]>, buffer: Box<[u32]>,
offset: Vector3<i32>, offset: Vector3<i32>,
dirty: bool, dirty: bool,
busy: bool, shift: Option<Vector3<i32>>,
queue: Vec<Vector3<i32>>, working: bool,
channel: (Sender<NodeBuffer>, Receiver<NodeBuffer>) channel: (Sender<NodeBuffer>, Receiver<NodeBuffer>)
} }
@@ -29,8 +29,9 @@ impl Nodes {
buffer: vec![0_u32; NODE_TEX_SIZE_QB].into_boxed_slice(), buffer: vec![0_u32; NODE_TEX_SIZE_QB].into_boxed_slice(),
offset: Vector3{x:0,y:0,z:0}, offset: Vector3{x:0,y:0,z:0},
dirty: false, dirty: false,
busy: false,
queue: Vec::new(), shift: None,
working: false,
channel: mpsc::channel() channel: mpsc::channel()
} }
} }
@@ -44,7 +45,7 @@ impl Nodes {
} }
pub fn is_busy(&self) -> bool { pub fn is_busy(&self) -> bool {
self.busy self.shift != None
} }
pub fn set_node(&mut self, index: usize, value: u32) { pub fn set_node(&mut self, index: usize, value: u32) {
@@ -53,31 +54,24 @@ impl Nodes {
} }
pub fn shift(&mut self, offset: &Vector3<i32>) { pub fn shift(&mut self, offset: &Vector3<i32>) {
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) { 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 // Check if there is some more work
if !self.busy { if !self.working {
if let Some(offset) = self.queue.pop() { if let Some(offset) = self.shift {
self.busy = true;
self.dirty = false;
let source = self.buffer.clone(); let source = self.buffer.clone();
let tx = self.channel.0.clone(); let tx = self.channel.0.clone();
self.working = true;
// Spawn worker // Spawn worker
thread::spawn(move || { thread::spawn(move || {
println!("shift worker start: {:?}", offset);
let size = NODE_TEX_SIZE as i32; let size = NODE_TEX_SIZE as i32;
let mut target = vec![0_u32; NODE_TEX_SIZE_QB].into_boxed_slice(); let mut target = vec![0_u32; NODE_TEX_SIZE_QB].into_boxed_slice();
let (ox, oy, oz) = (offset.x, offset.y, offset.z); let (ox, oy, oz) = (offset.x, offset.y, offset.z);
@@ -95,11 +89,19 @@ impl Nodes {
// Send result // Send result
tx.send((offset, target)).unwrap(); 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 { if self.dirty {
self.dirty = false; self.dirty = false;
+5 -6
View File
@@ -112,6 +112,11 @@ impl Renderer {
*/ */
pub fn render(&mut self) -> Result<(), wgpu::SwapChainError> { 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 // Update uniform buffer
let off = self.buffers.content.get_world_offset(); let off = self.buffers.content.get_world_offset();
let half = (buffers::nodes::NODE_TEX_SIZE / 2) as i32; 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.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])); 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 // Get next frame to render to
let timer = Instant::now(); let timer = Instant::now();
let frame = self.swapchain.get_current_frame()?.output; let frame = self.swapchain.get_current_frame()?.output;