From 0401f04ba971f49cba92d0c7da93cc8dc9f9a3de Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 28 Oct 2022 19:56:31 +0000 Subject: [PATCH] update camera projection if viewport changed (#5945) fixes https://github.com/bevyengine/bevy/issues/5944 Uses the second solution: > 2. keep track of the old viewport in the computed_state, and if camera.viewport != camera.computed_state.old_viewport, then update the projection. This is more reliable, but needs to store two UVec2s more in the camera (probably not a big deal). --- crates/bevy_render/src/camera/camera.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 88273f31f8..03cf6eed41 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -13,9 +13,8 @@ use bevy_ecs::{ component::Component, entity::Entity, event::EventReader, - query::Added, reflect::ReflectComponent, - system::{Commands, ParamSet, Query, Res}, + system::{Commands, Query, Res}, }; use bevy_math::{Mat4, Ray, UVec2, UVec4, Vec2, Vec3}; use bevy_reflect::prelude::*; @@ -68,6 +67,8 @@ pub struct RenderTargetInfo { pub struct ComputedCameraValues { projection_matrix: Mat4, target_info: Option, + // position and size of the `Viewport` + old_viewport_size: Option, } /// The defining component for camera entities, storing information about how and what to render @@ -404,10 +405,7 @@ pub fn camera_system( mut image_asset_events: EventReader>, windows: Res, images: Res>, - mut queries: ParamSet<( - Query<(Entity, &mut Camera, &mut T)>, - Query>, - )>, + mut cameras: Query<(&mut Camera, &mut T)>, ) { let mut changed_window_ids = Vec::new(); @@ -440,18 +438,21 @@ pub fn camera_system( }) .collect(); - let mut added_cameras = vec![]; - for entity in &queries.p1() { - added_cameras.push(entity); - } - for (entity, mut camera, mut camera_projection) in &mut queries.p0() { + for (mut camera, mut camera_projection) in &mut cameras { + let viewport_size = camera + .viewport + .as_ref() + .map(|viewport| viewport.physical_size); + if camera .target .is_changed(&changed_window_ids, &changed_image_handles) - || added_cameras.contains(&entity) + || camera.is_added() || camera_projection.is_changed() + || camera.computed.old_viewport_size != viewport_size { camera.computed.target_info = camera.target.get_render_target_info(&windows, &images); + camera.computed.old_viewport_size = viewport_size; if let Some(size) = camera.logical_viewport_size() { camera_projection.update(size.x, size.y); camera.computed.projection_matrix = camera_projection.get_projection_matrix();