From 4b64035cc47d0f4ace5eb73c9e96f8969b61b2f6 Mon Sep 17 00:00:00 2001 From: IceSentry Date: Fri, 9 Jun 2023 17:34:54 -0400 Subject: [PATCH 1/2] disable camera on window close --- crates/bevy_render/src/camera/camera.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index da0e4818ae216..0f34a7fec447c 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -24,7 +24,8 @@ use bevy_reflect::FromReflect; use bevy_transform::components::GlobalTransform; use bevy_utils::{HashMap, HashSet}; use bevy_window::{ - NormalizedWindowRef, PrimaryWindow, Window, WindowCreated, WindowRef, WindowResized, + NormalizedWindowRef, PrimaryWindow, Window, WindowClosed, WindowCreated, WindowRef, + WindowResized, }; use std::{borrow::Cow, ops::Range}; @@ -492,6 +493,9 @@ impl NormalizedRenderTarget { /// System in charge of updating a [`Camera`] when its window or projection changes. /// +/// The system will detect when a [`Window`] is closed and it disables any [`Camera`] that used that +/// [`Window`] has a [`RenderTarget`]. +/// /// The system detects window creation and resize events to update the camera projection if /// needed. It also queries any [`CameraProjection`] component associated with the same entity /// as the [`Camera`] one, to automatically update the camera projection matrix. @@ -509,9 +513,11 @@ impl NormalizedRenderTarget { /// [`OrthographicProjection`]: crate::camera::OrthographicProjection /// [`PerspectiveProjection`]: crate::camera::PerspectiveProjection /// [`Projection`]: crate::camera::Projection +#[allow(clippy::too_many_arguments)] pub fn camera_system( mut window_resized_events: EventReader, mut window_created_events: EventReader, + mut window_close_events: EventReader, mut image_asset_events: EventReader>, primary_window: Query>, windows: Query<(Entity, &Window)>, @@ -520,6 +526,18 @@ pub fn camera_system( ) { let primary_window = primary_window.iter().next(); + // Disable the camera associated to a window that's just been closed + for ev in window_close_events.iter() { + for (mut camera, _) in &mut cameras { + let Some(NormalizedRenderTarget::Window(window_ref)) = camera.target.normalize(primary_window) + else { continue; }; + + if window_ref.entity() == ev.window { + camera.is_active = false; + } + } + } + let mut changed_window_ids = HashSet::new(); changed_window_ids.extend(window_created_events.iter().map(|event| event.window)); changed_window_ids.extend(window_resized_events.iter().map(|event| event.window)); From d51578631f8422bb9c102978af3ceba499ee6ce8 Mon Sep 17 00:00:00 2001 From: icesentry Date: Sat, 10 Jun 2023 11:27:20 -0400 Subject: [PATCH 2/2] disable the graph instead --- crates/bevy_render/src/camera/camera.rs | 20 +------------------ .../src/camera/camera_driver_node.rs | 18 ++++++++++++++--- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 0f34a7fec447c..da0e4818ae216 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -24,8 +24,7 @@ use bevy_reflect::FromReflect; use bevy_transform::components::GlobalTransform; use bevy_utils::{HashMap, HashSet}; use bevy_window::{ - NormalizedWindowRef, PrimaryWindow, Window, WindowClosed, WindowCreated, WindowRef, - WindowResized, + NormalizedWindowRef, PrimaryWindow, Window, WindowCreated, WindowRef, WindowResized, }; use std::{borrow::Cow, ops::Range}; @@ -493,9 +492,6 @@ impl NormalizedRenderTarget { /// System in charge of updating a [`Camera`] when its window or projection changes. /// -/// The system will detect when a [`Window`] is closed and it disables any [`Camera`] that used that -/// [`Window`] has a [`RenderTarget`]. -/// /// The system detects window creation and resize events to update the camera projection if /// needed. It also queries any [`CameraProjection`] component associated with the same entity /// as the [`Camera`] one, to automatically update the camera projection matrix. @@ -513,11 +509,9 @@ impl NormalizedRenderTarget { /// [`OrthographicProjection`]: crate::camera::OrthographicProjection /// [`PerspectiveProjection`]: crate::camera::PerspectiveProjection /// [`Projection`]: crate::camera::Projection -#[allow(clippy::too_many_arguments)] pub fn camera_system( mut window_resized_events: EventReader, mut window_created_events: EventReader, - mut window_close_events: EventReader, mut image_asset_events: EventReader>, primary_window: Query>, windows: Query<(Entity, &Window)>, @@ -526,18 +520,6 @@ pub fn camera_system( ) { let primary_window = primary_window.iter().next(); - // Disable the camera associated to a window that's just been closed - for ev in window_close_events.iter() { - for (mut camera, _) in &mut cameras { - let Some(NormalizedRenderTarget::Window(window_ref)) = camera.target.normalize(primary_window) - else { continue; }; - - if window_ref.entity() == ev.window { - camera.is_active = false; - } - } - } - let mut changed_window_ids = HashSet::new(); changed_window_ids.extend(window_created_events.iter().map(|event| event.window)); changed_window_ids.extend(window_resized_events.iter().map(|event| event.window)); diff --git a/crates/bevy_render/src/camera/camera_driver_node.rs b/crates/bevy_render/src/camera/camera_driver_node.rs index b56bc52fc802a..38ba4ac185749 100644 --- a/crates/bevy_render/src/camera/camera_driver_node.rs +++ b/crates/bevy_render/src/camera/camera_driver_node.rs @@ -31,12 +31,24 @@ impl Node for CameraDriverNode { world: &World, ) -> Result<(), NodeRunError> { let sorted_cameras = world.resource::(); + let windows = world.resource::(); let mut camera_windows = HashSet::new(); for sorted_camera in &sorted_cameras.0 { - if let Ok(camera) = self.cameras.get_manual(world, sorted_camera.entity) { - if let Some(NormalizedRenderTarget::Window(window_ref)) = camera.target { - camera_windows.insert(window_ref.entity()); + let Ok(camera) = self.cameras.get_manual(world, sorted_camera.entity) else { + continue; + }; + + let mut run_graph = true; + if let Some(NormalizedRenderTarget::Window(window_ref)) = camera.target { + let window_entity = window_ref.entity(); + if windows.windows.get(&window_entity).is_some() { + camera_windows.insert(window_entity); + } else { + // The window doesn't exist anymore so we don't need to run the graph + run_graph = false; } + } + if run_graph { graph.run_sub_graph( camera.render_graph.clone(), vec![],