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).
This commit is contained in:
		
							parent
							
								
									fe7ebd4326
								
							
						
					
					
						commit
						0401f04ba9
					
				| @ -13,9 +13,8 @@ use bevy_ecs::{ | |||||||
|     component::Component, |     component::Component, | ||||||
|     entity::Entity, |     entity::Entity, | ||||||
|     event::EventReader, |     event::EventReader, | ||||||
|     query::Added, |  | ||||||
|     reflect::ReflectComponent, |     reflect::ReflectComponent, | ||||||
|     system::{Commands, ParamSet, Query, Res}, |     system::{Commands, Query, Res}, | ||||||
| }; | }; | ||||||
| use bevy_math::{Mat4, Ray, UVec2, UVec4, Vec2, Vec3}; | use bevy_math::{Mat4, Ray, UVec2, UVec4, Vec2, Vec3}; | ||||||
| use bevy_reflect::prelude::*; | use bevy_reflect::prelude::*; | ||||||
| @ -68,6 +67,8 @@ pub struct RenderTargetInfo { | |||||||
| pub struct ComputedCameraValues { | pub struct ComputedCameraValues { | ||||||
|     projection_matrix: Mat4, |     projection_matrix: Mat4, | ||||||
|     target_info: Option<RenderTargetInfo>, |     target_info: Option<RenderTargetInfo>, | ||||||
|  |     // position and size of the `Viewport`
 | ||||||
|  |     old_viewport_size: Option<UVec2>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// The defining component for camera entities, storing information about how and what to render
 | /// The defining component for camera entities, storing information about how and what to render
 | ||||||
| @ -404,10 +405,7 @@ pub fn camera_system<T: CameraProjection + Component>( | |||||||
|     mut image_asset_events: EventReader<AssetEvent<Image>>, |     mut image_asset_events: EventReader<AssetEvent<Image>>, | ||||||
|     windows: Res<Windows>, |     windows: Res<Windows>, | ||||||
|     images: Res<Assets<Image>>, |     images: Res<Assets<Image>>, | ||||||
|     mut queries: ParamSet<( |     mut cameras: Query<(&mut Camera, &mut T)>, | ||||||
|         Query<(Entity, &mut Camera, &mut T)>, |  | ||||||
|         Query<Entity, Added<Camera>>, |  | ||||||
|     )>, |  | ||||||
| ) { | ) { | ||||||
|     let mut changed_window_ids = Vec::new(); |     let mut changed_window_ids = Vec::new(); | ||||||
| 
 | 
 | ||||||
| @ -440,18 +438,21 @@ pub fn camera_system<T: CameraProjection + Component>( | |||||||
|         }) |         }) | ||||||
|         .collect(); |         .collect(); | ||||||
| 
 | 
 | ||||||
|     let mut added_cameras = vec![]; |     for (mut camera, mut camera_projection) in &mut cameras { | ||||||
|     for entity in &queries.p1() { |         let viewport_size = camera | ||||||
|         added_cameras.push(entity); |             .viewport | ||||||
|     } |             .as_ref() | ||||||
|     for (entity, mut camera, mut camera_projection) in &mut queries.p0() { |             .map(|viewport| viewport.physical_size); | ||||||
|  | 
 | ||||||
|         if camera |         if camera | ||||||
|             .target |             .target | ||||||
|             .is_changed(&changed_window_ids, &changed_image_handles) |             .is_changed(&changed_window_ids, &changed_image_handles) | ||||||
|             || added_cameras.contains(&entity) |             || camera.is_added() | ||||||
|             || camera_projection.is_changed() |             || 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.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() { |             if let Some(size) = camera.logical_viewport_size() { | ||||||
|                 camera_projection.update(size.x, size.y); |                 camera_projection.update(size.x, size.y); | ||||||
|                 camera.computed.projection_matrix = camera_projection.get_projection_matrix(); |                 camera.computed.projection_matrix = camera_projection.get_projection_matrix(); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jakob Hellermann
						Jakob Hellermann