//! Renders text to multiple windows with different scale factors using both Text and Text2d.1use bevy::{2camera::{visibility::RenderLayers, RenderTarget},3color::palettes::css::{LIGHT_CYAN, YELLOW},4prelude::*,5sprite::Text2dShadow,6window::{WindowRef, WindowResolution},7};89fn main() {10App::new()11// By default, a primary window is spawned by `WindowPlugin`, contained in `DefaultPlugins`.12// The primary window is given the `PrimaryWindow` marker component.13.add_plugins(DefaultPlugins.set(WindowPlugin {14primary_window: Some(Window {15title: "Primary window".to_owned(),16// Override the primary window's scale factor and use `1.` (no scaling).17resolution: WindowResolution::default().with_scale_factor_override(1.),18..default()19}),20..Default::default()21}))22.add_systems(Startup, setup_scene)23.run();24}2526fn setup_scene(mut commands: Commands) {27// The first camera; no render target is specified, its render target will be set to the primary window automatically.28// This camera has no `RenderLayers` component, so it only renders entities belonging to render layer `0`.29commands.spawn(Camera2d);3031// Spawn a second window32let secondary_window = commands33.spawn(Window {34title: "Secondary Window".to_owned(),35// Override the secondary window's scale factor and set it to double that of the primary window.36// This means the second window's text will use glyphs drawn at twice the resolution of the primary window's text,37// and they will be twice as big on screen.38resolution: WindowResolution::default().with_scale_factor_override(2.),39..default()40})41.id();4243// Spawn a second camera44let secondary_window_camera = commands45.spawn((46Camera2d,47// This camera will only render entities belonging to render layer `1`.48RenderLayers::layer(1),49Camera {50// Without an explicit render target, this camera would also target the primary window.51target: RenderTarget::Window(WindowRef::Entity(secondary_window)),52..default()53},54))55.id();5657let node = Node {58position_type: PositionType::Absolute,59top: Val::Px(12.0),60left: Val::Px(12.0),61..default()62};6364let text_font = TextFont::from_font_size(30.);6566// UI nodes can only be rendered by one camera at a time and ignore `RenderLayers`.67// This root UI node has no `UiTargetCamera` so `bevy_ui` will try to find a68// camera with the `IsDefaultUiCamera` marker component. When that fails (neither69// camera spawned here has an `IsDefaultUiCamera`), it queries for the70// first camera targeting the primary window and uses that.71commands.spawn(node.clone()).with_child((72Text::new("UI Text Primary Window"),73text_font.clone(),74TextShadow::default(),75));7677commands78.spawn((node, UiTargetCamera(secondary_window_camera)))79.with_child((80Text::new("UI Text Secondary Window"),81text_font.clone(),82TextShadow::default(),83));8485// `Text2d` belonging to render layer `0`.86commands.spawn((87Text2d::new("Text2d Primary Window"),88TextColor(YELLOW.into()),89text_font.clone(),90Text2dShadow::default(),91));9293// `Text2d` belonging to render layer `1`.94commands.spawn((95Text2d::new("Text2d Secondary Window"),96TextColor(YELLOW.into()),97text_font.clone(),98Text2dShadow::default(),99RenderLayers::layer(1),100));101102// This `Text2d` entity belongs to both render layers `0` and `1`, so it will be rendered by both103// cameras. A single text layout is generated per `Text2d` entity, targeting a specific scale104// factor. Since the two camera's render targets have different scale factors, the text layout105// will be generated using the higher scale factor (the secondary window's), and then downscaled when it is106// drawn by the camera targeting the primary window.107commands.spawn((108Text2d::new("Text2d Both Windows"),109TextColor(LIGHT_CYAN.into()),110text_font,111Text2dShadow::default(),112RenderLayers::from_layers(&[0, 1]),113Transform::from_xyz(0., -50., 0.),114));115}116117118