tirbofish/dropbear · commit
7192219e7306a1b7f358ee10885094bcfd2142d5
fix: antialiasing hot swapping fix
Signature present but could not be verified.
Unverified
@@ -637,6 +637,23 @@ Hardware: ); } + pub fn set_antialiasing(&mut self, antialiasing: AntiAliasingMode) -> bool { + if *self.antialiasing.read() == antialiasing { + return false; + } + + *self.antialiasing.write() = antialiasing; + + let config = self.config.read().clone(); + self.depth_texture = + Texture::depth_texture(&config, &self.device, antialiasing, Some("depth texture")); + self.hdr + .write() + .resize(&self.device, config.width, config.height, Some(antialiasing)); + + true + } + /// Resizes the offscreen viewport texture without touching the window surface. pub fn resize_viewport_texture(&mut self, width: u32, height: u32) { if width == 0 || height == 0 { @@ -1443,6 +1460,13 @@ impl ApplicationHandler for App { scene::SceneCommand::SetFPS(new_fps) => { self.set_target_fps(new_fps); } + scene::SceneCommand::SetAntialiasing(antialiasing) => { + if let Some((state, graphics)) = self.windows.get_mut(&window_id) { + if state.set_antialiasing(antialiasing) { + *graphics = Arc::new(graphics::SharedGraphicsContext::from_state(state)); + } + } + } scene::SceneCommand::ResizeViewport((width, height)) => { if let Some((state, graphics)) = self.windows.get_mut(&window_id) { state.resize_viewport_texture(width, height); @@ -7,6 +7,7 @@ use winit::event_loop::ActiveEventLoop; use winit::window::WindowId; use crate::{WindowData, graphics::SharedGraphicsContext, input}; +use crate::multisampling::AntiAliasingMode; use parking_lot::RwLock; use std::{collections::HashMap, rc::Rc, sync::Arc}; @@ -35,6 +36,7 @@ pub enum SceneCommand { RequestWindow(WindowData), CloseWindow(WindowId), SetFPS(u32), + SetAntialiasing(AntiAliasingMode), ResizeViewport((u32, u32)), } @@ -150,6 +152,7 @@ impl Manager { SceneCommand::RequestWindow(_) | SceneCommand::CloseWindow(_) | SceneCommand::SetFPS(_) + | SceneCommand::SetAntialiasing(_) | SceneCommand::ResizeViewport(_) => { return vec![command]; } @@ -68,6 +68,7 @@ use tokio::sync::oneshot; use transform_gizmo_egui::{EnumSet, Gizmo, GizmoMode, GizmoOrientation}; use wgpu::{Color, Extent3d}; use winit::dpi::PhysicalSize; +use dropbear_engine::multisampling::AntiAliasingMode; use winit::window::{CursorGrabMode, WindowAttributes}; use winit::{keyboard::KeyCode, window::Window}; @@ -177,6 +178,7 @@ pub struct Editor { pub(crate) play_mode_exit_rx: Option<std::sync::mpsc::Receiver<()>>, pub(crate) asset_clipboard: Option<AssetClipboard>, + pub(crate) pending_aa_reload: Option<AntiAliasingMode>, } impl Editor { @@ -292,6 +294,7 @@ impl Editor { play_mode_pid: None, play_mode_exit_rx: None, asset_clipboard: None, + pending_aa_reload: None, collider_wireframe_pipeline: None, instance_buffer_cache: HashMap::new(), animated_instance_buffer: None, @@ -1388,6 +1391,7 @@ impl Editor { pub fn load_wgpu_nerdy_stuff<'a>( &mut self, graphics: std::sync::Arc<dropbear_engine::graphics::SharedGraphicsContext>, + skybox_texture: Option<&Vec<u8>>, ) { self.main_render_pipeline = Some(MainRenderPipeline::new(graphics.clone())); self.light_cube_pipeline = Some(LightCubePipeline::new(graphics.clone())); @@ -1405,7 +1409,7 @@ impl Editor { let sky_texture = HdrLoader::from_equirectangular_bytes( &graphics.device, &graphics.queue, - DEFAULT_SKY_TEXTURE, + skybox_texture.map_or(DEFAULT_SKY_TEXTURE, |v| v.as_slice()), 1080, Some("sky texture"), ); @@ -1569,7 +1573,9 @@ impl UndoableAction { /// This enum will be used to describe the type of command/signal. This is only between /// the editor and unlike SceneCommand, this will ping a signal everywhere in that scene +#[derive(Default)] pub enum Signal { + #[default] None, Copy(SceneEntity), Paste(SceneEntity), @@ -1588,6 +1594,9 @@ pub enum Signal { /// Adds a new component instance using the async init pipeline. AddComponent(hecs::Entity, Box<dyn SerializedComponent>), RequestNewWindow(WindowData), + ReloadWGPUData{ + skybox_texture: Option<Vec<u8>> + }, UpdateViewportSize((f32, f32)), } @@ -149,8 +149,29 @@ impl Scene for Editor { log_once::debug_once!("Scene has fully loaded"); } + { + let desired = EDITOR_SETTINGS.read().anti_aliasing_mode; + let current = *graphics.antialiasing.read(); + + if desired != current { + if self.pending_aa_reload != Some(desired) + && matches!(self.scene_command, SceneCommand::None) + { + log::debug!("Anti aliasing mode changed, requesting WGPU update"); + self.scene_command = SceneCommand::SetAntialiasing(desired); + self.pending_aa_reload = Some(desired); + } + } else if self.pending_aa_reload.is_some() { + log::debug!("Anti aliasing mode applied, reloading WGPU data"); + self.signal = Signal::ReloadWGPUData { + skybox_texture: None, + }; + self.pending_aa_reload = None; + } + } + if !self.is_world_loaded.rendering_loaded && self.is_world_loaded.is_fully_loaded() { - self.load_wgpu_nerdy_stuff(graphics); + self.load_wgpu_nerdy_stuff(graphics, None); return; } @@ -226,21 +226,16 @@ impl Scene for EditorSettingsWindow { } }); { - let mut antialiasing = graphics.antialiasing.write(); ui.label("Anti-aliasing mode:"); ComboBox::from_id_salt("anti-aliasing-mode-combobox") - .selected_text(match *antialiasing { + .selected_text(match editor.anti_aliasing_mode { AntiAliasingMode::None => "None", AntiAliasingMode::MSAA4 => "MSAA4" }) .show_ui(ui, |ui| { - ui.selectable_value(&mut *antialiasing, AntiAliasingMode::None, "None"); - ui.selectable_value(&mut *antialiasing, AntiAliasingMode::MSAA4, "MSAA4"); + ui.selectable_value(&mut editor.anti_aliasing_mode, AntiAliasingMode::None, "None"); + ui.selectable_value(&mut editor.anti_aliasing_mode, AntiAliasingMode::MSAA4, "MSAA4"); }); - - if editor.anti_aliasing_mode != *antialiasing { - editor.anti_aliasing_mode = *antialiasing; - } } } @@ -9,7 +9,13 @@ use eucalyptus_core::{fatal, info, success, success_without_console, warn, warn_ use std::fs; use std::path::PathBuf; use std::sync::Arc; +use log::error; use winit::keyboard::KeyCode; +use dropbear_engine::pipelines::GlobalsUniform; +use dropbear_engine::pipelines::light_cube::LightCubePipeline; +use dropbear_engine::pipelines::shader::MainRenderPipeline; +use dropbear_engine::sky::{HdrLoader, SkyPipeline, DEFAULT_SKY_TEXTURE}; +use eucalyptus_core::physics::collider::shader::ColliderWireframePipeline; pub trait SignalController { fn run_signal(&mut self, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<()>; @@ -20,7 +26,7 @@ impl SignalController for Editor { let local_signal: Option<Signal> = None; let show = true; - match &self.signal { + match std::mem::replace(&mut self.signal, Signal::None) { Signal::None => { // returns absolutely nothing because no signal is set. Ok::<(), anyhow::Error>(()) @@ -29,7 +35,7 @@ impl SignalController for Editor { Signal::AssetCopy { source, division } => { self.asset_clipboard = Some(AssetClipboard { source: source.clone(), - division: *division, + division: division, }); self.signal = Signal::None; Ok(()) @@ -46,7 +52,7 @@ impl SignalController for Editor { } let clipboard = clipboard.unwrap(); - if clipboard.division != *division { + if clipboard.division != division { warn!("Cannot paste across different asset divisions"); self.signal = Signal::None; return Ok(()); @@ -521,7 +527,7 @@ impl SignalController for Editor { loader_future.await }; let handle = graphics.future_queue.push(init_future); - self.pending_components.push((*entity, handle)); + self.pending_components.push((entity, handle)); success!("Queued component addition for entity {:?}", entity); self.signal = Signal::None; @@ -545,6 +551,21 @@ impl SignalController for Editor { self.signal = Signal::None; Ok(()) } + Signal::ReloadWGPUData { skybox_texture } => { + self.main_render_pipeline = None; + self.light_cube_pipeline = None; + self.shader_globals = None; + self.collider_wireframe_pipeline = None; + self.mipmapper = None; + self.texture_id = None; + self.window = None; + self.sky_pipeline = None; + self.load_wgpu_nerdy_stuff(graphics.clone(), skybox_texture.as_ref()); + + self.signal = Signal::None; + + Ok(()) + } }?; if !show { self.signal = Signal::None; @@ -237,7 +237,18 @@ impl PlayMode { Ok(result) } - pub fn load_wgpu_nerdy_stuff<'a>(&mut self, graphics: Arc<SharedGraphicsContext>) { + pub fn reload_wgpu(&mut self, graphics: Arc<SharedGraphicsContext>, sky_texture: Option<&Vec<u8>>) { + self.light_cube_pipeline = None; + self.main_pipeline = None; + self.shader_globals = None; + self.collider_wireframe_pipeline = None; + self.kino = None; + self.sky_pipeline = None; + + self.load_wgpu_nerdy_stuff(graphics, sky_texture); + } + + pub fn load_wgpu_nerdy_stuff<'a>(&mut self, graphics: Arc<SharedGraphicsContext>, sky_texture: Option<&Vec<u8>>) { self.light_cube_pipeline = Some(LightCubePipeline::new(graphics.clone())); self.main_pipeline = Some(MainRenderPipeline::new(graphics.clone())); self.shader_globals = Some(GlobalsUniform::new( @@ -262,7 +273,7 @@ impl PlayMode { let sky_texture = HdrLoader::from_equirectangular_bytes( &graphics.device, &graphics.queue, - DEFAULT_SKY_TEXTURE, + sky_texture.map_or(DEFAULT_SKY_TEXTURE, |v| v.as_slice()), 1080, Some("sky texture"), ); @@ -511,7 +522,7 @@ impl PlayMode { progress.camera_received = true; self.scene_progress = Some(progress); - self.load_wgpu_nerdy_stuff(graphics.clone()); + self.load_wgpu_nerdy_stuff(graphics.clone(), None); self.reload_scripts_for_current_world(graphics.clone()); @@ -541,7 +552,7 @@ impl PlayMode { self.active_camera = Some(new_camera); } - self.load_wgpu_nerdy_stuff(graphics.clone()); + self.load_wgpu_nerdy_stuff(graphics.clone(), None); self.reload_scripts_for_current_world(graphics.clone()); self.current_scene = Some(scene_progress.requested_scene.clone());