aboutsummaryrefslogtreecommitdiff
path: root/client/src/renderer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/renderer.rs')
-rw-r--r--client/src/renderer.rs184
1 files changed, 166 insertions, 18 deletions
diff --git a/client/src/renderer.rs b/client/src/renderer.rs
index c8f7f0b..b213307 100644
--- a/client/src/renderer.rs
+++ b/client/src/renderer.rs
@@ -1,22 +1,44 @@
-use std::sync::Arc;
-
+use crate::skin_manager::{SkinManager, init_sprite_textures};
use anyhow::{Result, anyhow};
+use log::warn;
use pollster::FutureExt;
+use std::{sync::Arc, time::Instant};
use twgpu::{
- Camera, GpuCamera,
- map::{GpuMapData, GpuMapStatic},
- shared::Rng,
- sprites::{ParticleData, SpriteTextures, SpritesData, SpritesStatic},
+ Camera, GpuCamera, TwRenderPass,
+ blit::Blit,
+ buffer::GpuBuffer,
+ map::{GpuMapData, GpuMapRender, GpuMapStatic},
+ sprites::{ParticleData, ParticleGroup, SpriteTextures, SpritesData, SpritesStatic},
textures::Samplers,
};
+use twmap::TwMap;
+use vek::Vec2;
use wgpu::{
- Backends, DeviceDescriptor, Features, Instance, InstanceDescriptor, Limits, MemoryHints,
- PowerPreference, RequestAdapterOptions, TextureFormat,
+ Backends, Color, CommandEncoderDescriptor, Device, DeviceDescriptor, Features, Instance,
+ InstanceDescriptor, Limits, LoadOp, MaintainBase, MemoryHints, Operations, PowerPreference,
+ Queue, RenderPassColorAttachment, RenderPassDescriptor, RequestAdapterOptions, StoreOp,
+ Surface, SurfaceConfiguration, TextureFormat, TextureViewDescriptor,
};
-use winit::window::Window;
+use winit::{dpi::PhysicalSize, window::Window};
pub struct Renderer<'a> {
+ device: Arc<Device>,
+ queue: Arc<Queue>,
window: &'a Window,
+ surface: Surface<'a>,
+ surface_configuration: SurfaceConfiguration,
+ twmap: TwMap,
+ map_render: GpuMapRender,
+ map_data: GpuMapData,
+ camera: Camera,
+ sprites_data: SpritesData,
+ particle_data: ParticleData,
+ skin_manager: SkinManager,
+ sprites_static: SpritesStatic,
+ sprite_textures: SpriteTextures,
+ gpu_camera: Arc<GpuBuffer<Camera>>,
+ start: Instant,
+ need_reconfigure: bool,
}
impl<'a> Renderer<'a> {
@@ -51,9 +73,17 @@ impl<'a> Renderer<'a> {
None,
)
.block_on()?;
+ let device = Arc::new(device);
+ let queue = Arc::new(queue);
+
+ let mut twmap = TwMap::parse(include_bytes!(
+ "/home/muffin/etc/ddnet-maps/types/novice/maps/Mint.map"
+ ))?;
+
+ twmap.load()?;
let samplers = Arc::new(Samplers::new(&device));
- let mut camera = Camera::new(1.);
+ let camera = Camera::new(1.);
let gpu_camera = Arc::new(GpuCamera::upload(&camera, &device));
let map_static = GpuMapStatic::new(texture_format, &device);
@@ -62,15 +92,133 @@ impl<'a> Renderer<'a> {
map_static.prepare_render(&twmap, &map_data, &gpu_camera, &samplers, &device);
let sprites_static = SpritesStatic::new(texture_format, &device);
- let mut sprites_data = SpritesData::new(&device);
- let mut particle_data = ParticleData::new(demo.current_time(), &device);
- let mut textures = SpriteTextures::new(&device, &queue, &gpu_camera, &samplers);
- let mut rng = Rng::new(0);
- init_sprite_textures(&mut textures, twmap.version, &device, &queue)?;
+ let sprites_data = SpritesData::new(&device);
+ let particle_data = ParticleData::new(0.0, &device);
+ let mut sprite_textures = SpriteTextures::new(&device, &queue, &gpu_camera, &samplers);
+ init_sprite_textures(&mut sprite_textures, twmap.version, &device, &queue)?;
let blit = Arc::new(Blit::new(&device));
- let mut skin_manager = SkinManager::new(blit, &mut textures, device.clone(), queue.clone());
+ let skin_manager =
+ SkinManager::new(blit, &mut sprite_textures, device.clone(), queue.clone());
+
+ let surface_configuration = surface
+ .get_default_config(&adapter, 256, 256)
+ .ok_or(anyhow!("no surface config"))?;
+
+ surface.configure(&device, &surface_configuration);
+
+ Ok(Self {
+ start: Instant::now(),
+ map_data,
+ sprites_static,
+ window,
+ device,
+ queue,
+ twmap,
+ surface,
+ surface_configuration,
+ map_render,
+ camera,
+ gpu_camera,
+ particle_data,
+ skin_manager,
+ sprites_data,
+ sprite_textures,
+ need_reconfigure: false,
+ })
+ }
+ pub fn resize(&mut self, size: PhysicalSize<u32>) {
+ self.surface_configuration.width = size.width;
+ self.surface_configuration.height = size.height;
+ self.camera
+ .switch_aspect_ratio(size.width as f32 / size.height as f32);
+ self.reconfigure();
+ }
+ pub fn reconfigure(&mut self) {
+ self.surface
+ .configure(&self.device, &self.surface_configuration);
+ self.need_reconfigure = false;
+ }
+
+ pub fn redraw(&mut self) -> Result<()> {
+ if self.need_reconfigure {
+ self.reconfigure();
+ }
+ let target = self.surface.get_current_texture()?;
+ if target.suboptimal {
+ warn!("suboptimal surface, need reconfigure");
+ self.need_reconfigure = true;
+ }
+
+ let time = self.start.elapsed().as_micros() as i64;
+ let size = Vec2::new(
+ self.surface_configuration.width,
+ self.surface_configuration.height,
+ );
+ self.map_data
+ .update(&self.twmap, &self.camera, size, time, time, &self.queue);
+ self.gpu_camera.update(&self.camera, &self.queue);
+
+ let target_view = target
+ .texture
+ .create_view(&TextureViewDescriptor::default());
+
+ let mut commands = self
+ .device
+ .create_command_encoder(&CommandEncoderDescriptor { label: None });
+
+ {
+ let rpass = commands.begin_render_pass(&RenderPassDescriptor {
+ label: None,
+ color_attachments: &[Some(RenderPassColorAttachment {
+ view: &target_view,
+ resolve_target: None,
+ ops: Operations {
+ load: LoadOp::Clear(Color::BLACK),
+ store: StoreOp::Store,
+ },
+ })],
+ ..Default::default()
+ });
+ let mut rpass = TwRenderPass::new(rpass, size, &self.camera);
+ self.map_render.render_background(&mut rpass);
+ self.sprites_static.render_particles(
+ &self.particle_data,
+ ParticleGroup::Trails,
+ &self.sprite_textures,
+ &mut rpass.render_pass,
+ );
+ self.sprites_static.render(
+ &self.sprites_data,
+ &self.sprite_textures,
+ &mut rpass.render_pass,
+ );
+ self.map_render.render_foreground(&mut rpass);
+ self.sprites_static.render_particles(
+ &self.particle_data,
+ ParticleGroup::Explosions,
+ &self.sprite_textures,
+ &mut rpass.render_pass,
+ );
+ self.sprites_static.render_particles(
+ &self.particle_data,
+ ParticleGroup::Extra,
+ &self.sprite_textures,
+ &mut rpass.render_pass,
+ );
+ self.sprites_static.render_particles(
+ &self.particle_data,
+ ParticleGroup::General,
+ &self.sprite_textures,
+ &mut rpass.render_pass,
+ );
+ }
+
+ let submission = self.queue.submit(Some(commands.finish()));
+ self.device
+ .poll(MaintainBase::WaitForSubmissionIndex(submission));
+
+ target.present();
- Self { window }
+ Ok(())
}
- pub fn redraw() {}
}