diff options
| author | Jon Santmyer <jon@jonsantmyer.com> | 2026-05-21 07:58:47 -0400 |
|---|---|---|
| committer | Jon Santmyer <jon@jonsantmyer.com> | 2026-05-21 07:58:47 -0400 |
| commit | 14ca7b5fc15eb2618b46bde0cac85e37ebc9ebd9 (patch) | |
| tree | 6c4864880bc54778122f1c0e4fa195c16cc064db /src/tacmap.rs | |
| parent | a0a3b3974cab754c10a1517d82762b99482970ce (diff) | |
| download | systemic4x-14ca7b5fc15eb2618b46bde0cac85e37ebc9ebd9.tar.gz systemic4x-14ca7b5fc15eb2618b46bde0cac85e37ebc9ebd9.tar.bz2 systemic4x-14ca7b5fc15eb2618b46bde0cac85e37ebc9ebd9.zip | |
tacmap back as canvas. begin work on fleet scheduling
Diffstat (limited to 'src/tacmap.rs')
| -rw-r--r-- | src/tacmap.rs | 144 |
1 files changed, 137 insertions, 7 deletions
diff --git a/src/tacmap.rs b/src/tacmap.rs index 05747d4..e04db9d 100644 --- a/src/tacmap.rs +++ b/src/tacmap.rs @@ -13,11 +13,14 @@ use winit::keyboard::KeyCode; use crate::fleet::FleetsManager; use crate::solar_system::SolarSystem; use crate::solar_system::SystemId; +use crate::texture::Texture; use crate::timeman::Second; use crate::timeman::TimeMan; use crate::ui; +use crate::wgpuctx::RenderPassBuilder; use crate::wgpuctx::SceneCtx; use crate::wgpuctx::WgpuCtx; +use crate::wgpuctx::pipeline::RenderPipelineBuilder; use render::*; use body_render::*; @@ -27,6 +30,12 @@ use camera::*; pub struct TacticalMap { + canvas_size: winit::dpi::PhysicalSize<u32>, + canvas_texture: Option<Texture>, + canvas_pipeline: wgpu::RenderPipeline, + canvas_buffer: wgpu::Buffer, + canvas_bindgroup: wgpu::BindGroup, + camera: Camera, pmatrix: Projection, @@ -41,12 +50,71 @@ pub struct TacticalMap impl TacticalMap { + fn bindgroup_layout(device: &wgpu::Device) + -> wgpu::BindGroupLayout + { + device.create_bind_group_layout( + &wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None + }, + count: None, + } + ] + } + ) + } + pub fn new(wgpuctx: &WgpuCtx) -> Self { let surface_size = winit::dpi::PhysicalSize::new( wgpuctx.surface_config().width, wgpuctx.surface_config().height ); + + let canvas_shader = wgpuctx.create_shader( + wgpu::include_wgsl!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/assets/shaders/canvas.wgsl") + )); + + let canvas_texture_bindgroup_layout = Texture::bindgroup_layout(wgpuctx.device()); + let canvas_position_bindgroup_layout = Self::bindgroup_layout(wgpuctx.device()); + + let canvas_pipeline = RenderPipelineBuilder::new(&canvas_shader) + .primitive_topology(wgpu::PrimitiveTopology::TriangleStrip) + .cull_mode(None) + .add_bindgroup(&canvas_texture_bindgroup_layout) + .add_bindgroup(&canvas_position_bindgroup_layout) + .build(Some("Tactical map canvas pipeline"), wgpuctx); + + let canvas_buffer = wgpuctx.create_buffer( + &wgpu::BufferDescriptor { + label: None, + size: 4 * std::mem::size_of::<f32>() as u64, + usage: wgpu::BufferUsages::UNIFORM | + wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + } + ); + + let canvas_bindgroup = wgpuctx.device().create_bind_group( + &wgpu::BindGroupDescriptor { + label: None, + layout: &canvas_position_bindgroup_layout, + entries: &[ wgpu::BindGroupEntry { + binding: 0, + resource: canvas_buffer.as_entire_binding(), + }], + } + ); let camera = Camera::new( wgpuctx, @@ -61,6 +129,12 @@ impl TacticalMap (0.01, 1000.0)); Self { + canvas_size: winit::dpi::PhysicalSize::new(0, 0), + canvas_texture: None, + canvas_pipeline: canvas_pipeline, + canvas_buffer: canvas_buffer, + canvas_bindgroup: canvas_bindgroup, + camera: camera, pmatrix: projection, camera_controller: CameraController::new(), @@ -78,7 +152,12 @@ impl TacticalMap width: u32, height: u32) { - self.pmatrix.resize(width, height); + let new_size = winit::dpi::PhysicalSize::new(width, height); + if self.canvas_size != new_size { + self.pmatrix.resize(width, height); + self.canvas_size = new_size; + self.canvas_texture = None; + } } pub fn update( @@ -103,15 +182,36 @@ impl TacticalMap pub fn prepare( &mut self, - scene: &mut SceneCtx, + rect: egui::Rect, wgpuctx: &WgpuCtx, fleets_man: &FleetsManager, solar_system: &SolarSystem, timeman: &TimeMan, ) -> Result<(), ()> { + //Prepare canvas + if self.canvas_texture.is_none() { + println!("Rebuilding canvas texture to {:?}", rect); + self.canvas_texture = Some(wgpuctx.new_texture( + wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: self.canvas_size.width, + height: self.canvas_size.height, + depth_or_array_layers: 1 + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpuctx.surface_config().format, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT | + wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &wgpuctx.surface_config().view_formats + } + )); + } + self.camera.update_buffer(wgpuctx, &self.pmatrix); - self.camera.stage_changes(scene.encoder_mut()); if self.system_for_render.is_none() || self.system_for_render.unwrap() != solar_system.id() { @@ -151,6 +251,34 @@ impl TacticalMap Err(e) => println!("Tactical map fleet render update error: {}", e) } + let window_width = wgpuctx.surface_config().width as f32; + let window_height = wgpuctx.surface_config().height as f32; + wgpuctx.queue().write_buffer(&self.canvas_buffer, 0, + bytemuck::cast_slice(&[ + rect.min.x / window_width, + rect.min.y / window_height, + rect.width() / window_width, + rect.height() / window_height + ])); + + let canvas_view = self.canvas_texture.as_ref().unwrap().view(); + let mut canvas_scene = SceneCtx::from_view_default(wgpuctx, canvas_view, Some("Tactical map canvas scene")); + + self.camera.stage_changes(canvas_scene.encoder_mut()); + + { + let mut pass = RenderPassBuilder::new(Some("Tactical map render pass"), canvas_view) + .clear_color(wgpu::Color { r: 0.0, g: 0.0, b: 0.1, a: 1.0 }) + .build_from_scene(&mut canvas_scene); + + self.grid_renderer.render( &mut pass, &self.camera); + self.orbit_renderer.render(&mut pass, &self.camera); + self.fleet_renderer.render(&mut pass, &self.camera); + self.body_renderer.render( &mut pass, &self.camera); + } + + canvas_scene.submit(wgpuctx); + Ok(()) } @@ -158,10 +286,12 @@ impl TacticalMap &self, pass: &mut wgpu::RenderPass<'_>) { - self.grid_renderer.render( pass, &self.camera); - self.orbit_renderer.render(pass, &self.camera); - self.fleet_renderer.render(pass, &self.camera); - self.body_renderer.render( pass, &self.camera); + pass.set_pipeline(&self.canvas_pipeline); + + self.canvas_texture.as_ref().unwrap().use_on_pass(pass, 0); + pass.set_bind_group(1, &self.canvas_bindgroup, &[]); + + pass.draw(0..4, 0..1); } pub fn paint_labels( |
