diff --git a/src/example.rs b/src/example.rs index a11f5d48..c4cb1020 100644 --- a/src/example.rs +++ b/src/example.rs @@ -4,7 +4,7 @@ pub const MUNICH_X: u32 = 17425; pub const MUNICH_Y: u32 = 11365; pub const MUNICH_Z: u8 = 15; -pub fn fetch_munich_tiles(worker_loop: &WorkerLoop) { +pub fn fetch_munich_tiles(worker_loop: &mut WorkerLoop) { // This size matches the amount of tiles which are loaded on zoom 15 on FHD for x in 0..8 { for y in 0..5 { diff --git a/src/io/worker_loop.rs b/src/io/worker_loop.rs index 8ce2f475..f5cfb4a1 100644 --- a/src/io/worker_loop.rs +++ b/src/io/worker_loop.rs @@ -1,4 +1,4 @@ -use std::collections::VecDeque; +use std::collections::{HashSet, VecDeque}; use std::sync::{Arc, Condvar, Mutex}; @@ -22,6 +22,7 @@ pub struct TesselatedLayer { #[derive(Clone)] pub struct WorkerLoop { + loaded_coords: Arc>>, requests: Arc>, responses: Arc>, } @@ -35,14 +36,28 @@ impl Drop for WorkerLoop { impl WorkerLoop { pub fn new() -> Self { Self { + loaded_coords: Arc::new(Mutex::new(HashSet::new())), requests: Arc::new(WorkQueue::new()), responses: Arc::new(WorkQueue::new()), } } - pub fn fetch(&self, coords: TileCoords) { - info!("new tile request: {:?}", &coords); - self.requests.push(coords); + pub fn is_loaded(&self, coords: &TileCoords) -> bool { + if let Ok(loaded_coords) = self.loaded_coords.lock() { + loaded_coords.contains(coords) + } else { + false + } + } + pub fn fetch(&mut self, coords: TileCoords) { + if let Ok(mut loaded_coords) = self.loaded_coords.lock() { + if loaded_coords.contains(&coords) { + return; + } + loaded_coords.insert(coords); + info!("new tile request: {:?}", &coords); + self.requests.push(coords); + } } pub fn pop_all(&self) -> Vec { diff --git a/src/main_loop.rs b/src/main_loop.rs index 1b09d1f2..9a5645f2 100644 --- a/src/main_loop.rs +++ b/src/main_loop.rs @@ -11,12 +11,12 @@ use crate::render::render_state::RenderState; pub async fn setup( window: winit::window::Window, event_loop: EventLoop<()>, - worker_loop: Box, + mut worker_loop: Box, ) { info!("== mapr =="); - fetch_munich_tiles(worker_loop.as_ref()); - + /* fetch_munich_tiles(worker_loop.as_ref()); + */ let mut input = InputController::new(0.2, 100.0); let mut maybe_state: Option = if cfg!(target_os = "android") { None @@ -84,7 +84,7 @@ pub async fn setup( let dt = now - last_render_time; last_render_time = now; input.update_state(state, dt); - state.upload_tile_geometry(&worker_loop); + state.upload_tile_geometry(&mut worker_loop); match state.render() { Ok(_) => {} Err(wgpu::SurfaceError::Lost) => { diff --git a/src/render/render_state.rs b/src/render/render_state.rs index 36b43d79..92322f49 100644 --- a/src/render/render_state.rs +++ b/src/render/render_state.rs @@ -1,6 +1,8 @@ +use cgmath::{Point3, Vector3}; use std::default::Default; use std::{cmp, iter}; +use crate::coords::{TileCoords, WorldCoords, WorldTileCoords}; use wgpu::{Buffer, Limits, Queue}; use winit::dpi::PhysicalSize; use winit::window::Window; @@ -347,9 +349,27 @@ impl RenderState { // TODO: Could we draw inspiration from StagingBelt (https://docs.rs/wgpu/latest/wgpu/util/struct.StagingBelt.html)? // TODO: What is StagingBelt for? - pub fn upload_tile_geometry(&mut self, worker_loop: &WorkerLoop) { - println!("1: {:?}", self.camera.view_bounding_box(&self.perspective)); - println!("2: {:?}", self.camera.view_bounding_box2(&self.perspective)); + pub fn upload_tile_geometry(&mut self, worker_loop: &mut WorkerLoop) { + if let Some(view_box) = self.camera.view_bounding_box(&self.perspective) { + /*let view_box = self.camera.view_bounding_box2(&self.perspective).unwrap();*/ + + let min_world: WorldCoords = Point3::new(view_box.min.x, view_box.min.y, 15.0).into(); + let min_world_tile: WorldTileCoords = min_world.into(); + let min_tile: TileCoords = min_world_tile.into(); + let max_world: WorldCoords = Point3::new(view_box.max.x, view_box.max.y, 15.0).into(); + let max_world_tile: WorldTileCoords = max_world.into(); + let max_tile: TileCoords = max_world_tile.into(); + + for x in min_tile.x..max_tile.x + 1 { + for y in min_tile.y..max_tile.y + 1 { + let to_be_fetched = (x, y, 15).into(); + if !worker_loop.is_loaded(&to_be_fetched) { + // FIXME: is_loaded is not correct right now + worker_loop.fetch(to_be_fetched); + } + } + } + } let upload = worker_loop.pop_all(); @@ -468,9 +488,18 @@ impl RenderState { { // Draw masks pass.set_pipeline(&self.mask_pipeline); - pass.set_vertex_buffer(0, self.tile_mask_instances_buffer.slice(..)); - // Draw 7 squares each out of 6 vertices - pass.draw(0..6, 0..self.tile_mask_pattern.instances()); + let masks = self.tile_mask_pattern.as_slice(); + if !masks.is_empty() { + pass.set_vertex_buffer( + 0, + self.tile_mask_instances_buffer.slice( + 0..masks.len() as u64 + * std::mem::size_of::() as u64, + ), + ); + // Draw 7 squares each out of 6 vertices + pass.draw(0..6, 0..self.tile_mask_pattern.instances()); + } } { for entry in self.buffer_pool.available_vertices() {