From 7b842e373e990445ffb57d5f2fa97786d6d5acdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Mockers?= Date: Thu, 21 Mar 2024 00:50:08 +0100 Subject: [PATCH] UI: rounded border should use camera instead of windows (#12601) # Objective - #12500 use the primary window resolution to do all its calculation. This means bad support for multiple windows or multiple ui camera ## Solution - Use camera driven UI (https://github.com/bevyengine/bevy/pull/10559) --- crates/bevy_ui/src/render/mod.rs | 49 +++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 882a87ba484b5..49b3fb1ad979a 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -9,7 +9,6 @@ use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d}; use bevy_hierarchy::Parent; use bevy_render::{render_phase::PhaseItem, view::ViewVisibility, ExtractSchedule, Render}; use bevy_sprite::{SpriteAssetEvents, TextureAtlas}; -use bevy_window::{PrimaryWindow, Window}; pub use pipeline::*; pub use render_pass::*; pub use ui_material_pipeline::*; @@ -181,7 +180,7 @@ pub struct ExtractedUiNodes { pub fn extract_uinode_background_colors( mut extracted_uinodes: ResMut, - windows: Extract>>, + camera_query: Extract>, default_ui_camera: Extract, ui_scale: Extract>, uinode_query: Extract< @@ -197,12 +196,6 @@ pub fn extract_uinode_background_colors( )>, >, ) { - let viewport_size = windows - .get_single() - .map(|window| window.resolution.size()) - .unwrap_or(Vec2::ZERO) - * ui_scale.0; - for ( entity, uinode, @@ -224,8 +217,22 @@ pub fn extract_uinode_background_colors( continue; } + let ui_logical_viewport_size = camera_query + .get(camera_entity) + .ok() + .and_then(|(_, c)| c.logical_viewport_size()) + .unwrap_or(Vec2::ZERO) + // The logical window resolution returned by `Window` only takes into account the window scale factor and not `UiScale`, + // so we have to divide by `UiScale` to get the size of the UI viewport. + / ui_scale.0; + let border_radius = if let Some(border_radius) = border_radius { - resolve_border_radius(border_radius, uinode.size(), viewport_size, ui_scale.0) + resolve_border_radius( + border_radius, + uinode.size(), + ui_logical_viewport_size, + ui_scale.0, + ) } else { [0.; 4] }; @@ -257,7 +264,7 @@ pub fn extract_uinode_background_colors( pub fn extract_uinode_images( mut commands: Commands, mut extracted_uinodes: ResMut, - windows: Extract>>, + camera_query: Extract>, texture_atlases: Extract>>, ui_scale: Extract>, default_ui_camera: Extract, @@ -275,12 +282,6 @@ pub fn extract_uinode_images( )>, >, ) { - let viewport_size = windows - .get_single() - .map(|window| window.resolution.size()) - .unwrap_or(Vec2::ZERO) - * ui_scale.0; - for (uinode, transform, view_visibility, clip, camera, image, atlas, slices, border_radius) in &uinode_query { @@ -326,8 +327,22 @@ pub fn extract_uinode_images( ), }; + let ui_logical_viewport_size = camera_query + .get(camera_entity) + .ok() + .and_then(|(_, c)| c.logical_viewport_size()) + .unwrap_or(Vec2::ZERO) + // The logical window resolution returned by `Window` only takes into account the window scale factor and not `UiScale`, + // so we have to divide by `UiScale` to get the size of the UI viewport. + / ui_scale.0; + let border_radius = if let Some(border_radius) = border_radius { - resolve_border_radius(border_radius, uinode.size(), viewport_size, ui_scale.0) + resolve_border_radius( + border_radius, + uinode.size(), + ui_logical_viewport_size, + ui_scale.0, + ) } else { [0.; 4] };