From e49e45da7edd54f84efaf8794d2f1736c0b7da43 Mon Sep 17 00:00:00 2001 From: Lily Lyons Date: Thu, 14 Sep 2023 22:12:59 -0700 Subject: [PATCH] feat(tilemap): :sparkles: Add layer darkening --- src/components/map_view.rs | 16 +++++++++++++++- src/components/tilepicker.rs | 2 +- src/graphics/map.rs | 9 +++++++-- src/graphics/primitives/tiles/mod.rs | 11 +++++++++++ src/graphics/primitives/tiles/shader.rs | 2 +- src/graphics/primitives/tiles/tilemap.wgsl | 3 ++- src/tabs/map.rs | 22 +++++++++++++--------- 7 files changed, 50 insertions(+), 15 deletions(-) diff --git a/src/components/map_view.rs b/src/components/map_view.rs index 7f80739f..53cbce3e 100644 --- a/src/components/map_view.rs +++ b/src/components/map_view.rs @@ -34,6 +34,8 @@ pub struct MapView { pub event_enabled: bool, pub snap_to_grid: bool, + pub darken_unselected_layers: bool, + pub scale: f32, } @@ -72,6 +74,8 @@ impl MapView { event_enabled: true, snap_to_grid: false, + darken_unselected_layers: true, + scale: 100., }) } @@ -162,7 +166,17 @@ impl MapView { max: canvas_pos + pos, }; - self.map.paint(ui.painter(), map_rect); + self.map.paint( + ui.painter(), + match self.selected_layer { + SelectedLayer::Events => None, + SelectedLayer::Tiles(selected_layer) if self.darken_unselected_layers => { + Some(selected_layer) + } + SelectedLayer::Tiles(_) => None, + }, + map_rect, + ); ui.painter().rect_stroke( map_rect, diff --git a/src/components/tilepicker.rs b/src/components/tilepicker.rs index 16c5e948..30753ee2 100644 --- a/src/components/tilepicker.rs +++ b/src/components/tilepicker.rs @@ -117,7 +117,7 @@ impl Tilepicker { tiles, viewport, .. } = resources.as_ref(); - tiles.draw(viewport, &[true], render_pass); + tiles.draw(viewport, &[true], None, render_pass); }), ), }); diff --git a/src/graphics/map.rs b/src/graphics/map.rs index 4202a644..a1600c96 100644 --- a/src/graphics/map.rs +++ b/src/graphics/map.rs @@ -104,7 +104,12 @@ impl Map { self.resources.tiles.set_tile(tile_id, position); } - pub fn paint(&mut self, painter: &egui::Painter, rect: egui::Rect) { + pub fn paint( + &mut self, + painter: &egui::Painter, + selected_layer: Option, + rect: egui::Rect, + ) { if self.ani_instant.elapsed() >= Duration::from_secs_f32((1. / 60.) * 16.) { self.ani_instant = Instant::now(); self.resources.tiles.autotiles.inc_ani_index(); @@ -151,7 +156,7 @@ impl Map { } } - tiles.draw(viewport, &enabled_layers, render_pass); + tiles.draw(viewport, &enabled_layers, selected_layer, render_pass); if fog_enabled { if let Some(fog) = fog { fog.draw(viewport, render_pass); diff --git a/src/graphics/primitives/tiles/mod.rs b/src/graphics/primitives/tiles/mod.rs index b5b53fa6..ec2f41f9 100644 --- a/src/graphics/primitives/tiles/mod.rs +++ b/src/graphics/primitives/tiles/mod.rs @@ -55,6 +55,7 @@ impl Tiles { &'rpass self, viewport: &primitives::Viewport, enabled_layers: &[bool], + selected_layer: Option, render_pass: &mut wgpu::RenderPass<'rpass>, ) { #[repr(C)] @@ -78,6 +79,16 @@ impl Tiles { self.atlas.bind(render_pass); for (layer, enabled) in enabled_layers.iter().copied().enumerate() { + let opacity = match selected_layer { + Some(selected_layer) if selected_layer == layer => 1.0, + Some(_) => 0.5, + None => 1.0, + }; + render_pass.set_push_constants( + wgpu::ShaderStages::FRAGMENT, + 64 + 36, + bytemuck::bytes_of::(&opacity), + ); if enabled { self.instances.draw(render_pass, layer); } diff --git a/src/graphics/primitives/tiles/shader.rs b/src/graphics/primitives/tiles/shader.rs index a55231c0..6e68d88b 100644 --- a/src/graphics/primitives/tiles/shader.rs +++ b/src/graphics/primitives/tiles/shader.rs @@ -47,7 +47,7 @@ impl Shader { // Fragment wgpu::PushConstantRange { stages: wgpu::ShaderStages::FRAGMENT, - range: (64 + 36)..(64 + 36 + 8), + range: (64 + 36)..(64 + 36 + 4), }, ], }); diff --git a/src/graphics/primitives/tiles/tilemap.wgsl b/src/graphics/primitives/tiles/tilemap.wgsl index 8209b2de..9d3fe093 100644 --- a/src/graphics/primitives/tiles/tilemap.wgsl +++ b/src/graphics/primitives/tiles/tilemap.wgsl @@ -17,7 +17,7 @@ struct VertexOutput { struct PushConstants { viewport: Viewport, autotiles: Autotiles, - opacity: u32, + opacity: f32, } struct Viewport { @@ -92,6 +92,7 @@ var atlas_sampler: sampler; @fragment fn fs_main(input: VertexOutput) -> @location(0) vec4 { var color = textureSample(atlas, atlas_sampler, input.tex_coords); + color.a *= push_constants.opacity; if color.a <= 0.0 { discard; diff --git a/src/tabs/map.rs b/src/tabs/map.rs index 0bb16d5c..f5ae6822 100644 --- a/src/tabs/map.rs +++ b/src/tabs/map.rs @@ -82,13 +82,11 @@ impl Tab { for (x, y) in x_array.into_iter().zip(y_array.into_iter()) { bitfield <<= 1; // Out-of-bounds tiles always count as valid neighbors - if ((x == -1 && position.0 == 0) || (x == 1 && position.0 + 1 == map.data.xsize())) - || ((y == -1 && position.1 == 0) || (y == 1 && position.1 + 1 == map.data.ysize())) - { - bitfield |= 1; - } + let is_out_of_bounds = ((x == -1 && position.0 == 0) + || (x == 1 && position.0 + 1 == map.data.xsize())) + || ((y == -1 && position.1 == 0) || (y == 1 && position.1 + 1 == map.data.ysize())); // Otherwise, we only consider neighbors that are autotiles of the same type - else if map.data[( + let is_same_autotile = map.data[( if x == -1 { position.0 - 1 } else { @@ -101,9 +99,10 @@ impl Tab { }, position.2, )] / 48 - == autotile - { - bitfield |= 1; + == autotile; + + if is_out_of_bounds || is_same_autotile { + bitfield |= 1 } } @@ -287,6 +286,11 @@ impl tab::Tab for Tab { .on_hover_text("Preview event page move routes"); ui.checkbox(&mut self.view.snap_to_grid, "Snap to grid") .on_hover_text("Snap's the viewport to the tile grid"); + ui.checkbox( + &mut self.view.darken_unselected_layers, + "Darken unselected layers", + ) + .on_disabled_hover_text("Toggles darkening unselected layers"); /* if ui.button("Save map preview").clicked() {