summaryrefslogtreecommitdiffstats
path: root/src/tacmap.rs
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-05-21 07:58:47 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-05-21 07:58:47 -0400
commit14ca7b5fc15eb2618b46bde0cac85e37ebc9ebd9 (patch)
tree6c4864880bc54778122f1c0e4fa195c16cc064db /src/tacmap.rs
parenta0a3b3974cab754c10a1517d82762b99482970ce (diff)
downloadsystemic4x-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.rs144
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(