diff options
Diffstat (limited to 'client/src/renderer.rs')
-rw-r--r-- | client/src/renderer.rs | 105 |
1 files changed, 98 insertions, 7 deletions
diff --git a/client/src/renderer.rs b/client/src/renderer.rs index b213307..57e0fc4 100644 --- a/client/src/renderer.rs +++ b/client/src/renderer.rs @@ -1,17 +1,26 @@ -use crate::skin_manager::{SkinManager, init_sprite_textures}; +use crate::{ + client::Client, + skin_manager::{SkinManager, init_sprite_textures}, +}; use anyhow::{Result, anyhow}; use log::warn; use pollster::FutureExt; -use std::{sync::Arc, time::Instant}; +use std::{mem::swap, random::random, sync::Arc, time::Instant}; +use twgame::Map; use twgpu::{ Camera, GpuCamera, TwRenderPass, blit::Blit, buffer::GpuBuffer, map::{GpuMapData, GpuMapRender, GpuMapStatic}, - sprites::{ParticleData, ParticleGroup, SpriteTextures, SpritesData, SpritesStatic}, + shared::{Clock, Rng}, + sprites::{ + ParticleData, ParticleGroup, SpriteRenderContext, SpriteTextures, SpritesData, + SpritesStatic, TeeStorage, + }, textures::Samplers, }; use twmap::TwMap; +use twsnap::Snap; use vek::Vec2; use wgpu::{ Backends, Color, CommandEncoderDescriptor, Device, DeviceDescriptor, Features, Instance, @@ -22,6 +31,8 @@ use wgpu::{ use winit::{dpi::PhysicalSize, window::Window}; pub struct Renderer<'a> { + client: Arc<Client>, + device: Arc<Device>, queue: Arc<Queue>, window: &'a Window, @@ -38,12 +49,20 @@ pub struct Renderer<'a> { sprite_textures: SpriteTextures, gpu_camera: Arc<GpuBuffer<Camera>>, start: Instant, + rng: Rng, need_reconfigure: bool, + clock: Clock, + map: Map, + from_snap: Snap, + to_snap: Snap, + tees: TeeStorage, + clock_set: bool, + local_time_offset: i64, } impl<'a> Renderer<'a> { - pub fn new(window: &'a Window) -> Result<Self> { - let texture_format = TextureFormat::Bgra8UnormSrgb; + pub fn new(window: &'a Window, client: Arc<Client>) -> Result<Self> { + let texture_format = TextureFormat::Bgra8Unorm; let instance = Instance::new(InstanceDescriptor { backends: Backends::all(), @@ -83,7 +102,8 @@ impl<'a> Renderer<'a> { twmap.load()?; let samplers = Arc::new(Samplers::new(&device)); - let camera = Camera::new(1.); + let mut camera = Camera::new(1.); + camera.position = Vec2 { x: 33., y: 84. }; let gpu_camera = Arc::new(GpuCamera::upload(&camera, &device)); let map_static = GpuMapStatic::new(texture_format, &device); @@ -100,12 +120,16 @@ impl<'a> Renderer<'a> { let skin_manager = SkinManager::new(blit, &mut sprite_textures, device.clone(), queue.clone()); - let surface_configuration = surface + let mut surface_configuration = surface .get_default_config(&adapter, 256, 256) .ok_or(anyhow!("no surface config"))?; + surface_configuration.format = texture_format; // surface_configuration.format.remove_srgb_suffix(); + surface.configure(&device, &surface_configuration); + let map = Map::try_from(&mut twmap).map_err(|e| anyhow!("{e}"))?; + Ok(Self { start: Instant::now(), map_data, @@ -123,7 +147,16 @@ impl<'a> Renderer<'a> { skin_manager, sprites_data, sprite_textures, + clock: Clock::default(), + from_snap: Snap::default(), + to_snap: Snap::default(), + map, + local_time_offset: 0, + clock_set: false, + tees: TeeStorage::default(), + rng: Rng::new(random()), need_reconfigure: false, + client, }) } pub fn resize(&mut self, size: PhysicalSize<u32>) { @@ -150,13 +183,70 @@ impl<'a> Renderer<'a> { } let time = self.start.elapsed().as_micros() as i64; + let local_tick = (time + self.local_time_offset) as f64 / 1_000_000. * 50. + 1.; let size = Vec2::new( self.surface_configuration.width, self.surface_configuration.height, ); + + if self.clock_set { + self.clock.update(local_tick); + } + + for (player_id, player) in self.from_snap.players.iter() { + if player.local { + if let Some(tees) = self.tees.lerp_tee( + player_id, + &self.clock, + &self.from_snap, + &self.to_snap, + &self.map, + ) { + self.camera.position = self.clock.lerp_tee_vec(tees, |tee| tee.pos); + } + } + } + + { + let process = if let Ok((new_tick, new_snap)) = self.client.incoming.try_recv() { + eprintln!("{new_tick} {}", new_snap.players.len()); + if self.clock_set { + self.clock.next_tick(new_tick); + } else { + self.clock = Clock::new(new_tick); + self.clock_set = true; + } + self.local_time_offset = new_tick as i64 * 20_000 - time; + self.skin_manager.queue_snap_skins(&new_snap); + swap(&mut self.from_snap, &mut self.to_snap); + self.to_snap = new_snap; + true + } else { + false + }; + let mut ctx = SpriteRenderContext { + clock: &self.clock, + from_snap: &self.from_snap, + to_snap: &self.to_snap, + tees: &mut self.tees, + map: &self.map, + particles: &mut self.particle_data, + textures: &self.sprite_textures, + rng: &mut self.rng, + }; + if process { + ctx.process_events(); + } + self.sprites_data.clear(); + ctx.generate_all_sprites(&mut self.sprites_data); + } + self.map_data .update(&self.twmap, &self.camera, size, time, time, &self.queue); self.gpu_camera.update(&self.camera, &self.queue); + self.skin_manager.poll_queued(&mut self.sprite_textures); + self.sprites_data.upload(&self.device, &self.queue); + self.particle_data.upload(&self.device, &self.queue); let target_view = target .texture @@ -218,6 +308,7 @@ impl<'a> Renderer<'a> { .poll(MaintainBase::WaitForSubmissionIndex(submission)); target.present(); + self.window.request_redraw(); Ok(()) } |