bevy/examples/window/multiple_windows.rs
ickshonpe a6144e3e5c
extract_text_shadows camera query fix (#17930)
# Objective

`extract_text_shadows` was still using `UiTargetCamera` and
`DefaultUiCamera` for UI camera resolution, which no longer always
selects the right camera.

To see this modify the last lines of the `multiple_windows` example
from:
```rust
    commands.spawn((
        Text::new("First window"),
        node.clone(),
        // Since we are using multiple cameras, we need to specify which camera UI should be rendered to
        UiTargetCamera(first_window_camera),
    ));

    commands.spawn((
        Text::new("Second window"),
        node,
        UiTargetCamera(second_window_camera),
    ));
```
to:
```rust
    commands
        .spawn((
            node.clone(),
            // Since we are using multiple cameras, we need to specify which camera UI should be rendered to
            UiTargetCamera(first_window_camera),
        ))
        .with_child((Text::new("First window"), TextShadow::default()));

    commands
        .spawn((node, UiTargetCamera(second_window_camera)))
        .with_child((Text::new("Second window"), TextShadow::default()));
```

which results in the shadow that is meant to be displayed for the
"Second Window" label instead being written over the first:

<img width="800" alt="first_window_label"
src="https://github.com/user-attachments/assets/2eebccba-5749-4064-bb1c-e4f25ff0baf7">

## Solution
Remove the `UiTargetCamera` query and the `default_camera` parameter
from `extract_text_shadows` and use `UiCameraMap` with
`ComputedNodeTarget` instead.

## Testing
The `multiple_windows` example for this PR has been updated to add text
shadow to the window labels. You should see that it displays the "Second
Window" label's shadow correctly now.
2025-03-10 21:22:14 +00:00

69 lines
2.0 KiB
Rust

//! Uses two windows to visualize a 3D model from different angles.
use bevy::{prelude::*, render::camera::RenderTarget, window::WindowRef};
fn main() {
App::new()
// By default, a primary window gets spawned by `WindowPlugin`, contained in `DefaultPlugins`
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup_scene)
.run();
}
fn setup_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
// add entities to the world
commands.spawn(SceneRoot(
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/torus/torus.gltf")),
));
// light
commands.spawn((
DirectionalLight::default(),
Transform::from_xyz(3.0, 3.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y),
));
let first_window_camera = commands
.spawn((
Camera3d::default(),
Transform::from_xyz(0.0, 0.0, 6.0).looking_at(Vec3::ZERO, Vec3::Y),
))
.id();
// Spawn a second window
let second_window = commands
.spawn(Window {
title: "Second window".to_owned(),
..default()
})
.id();
let second_window_camera = commands
.spawn((
Camera3d::default(),
Transform::from_xyz(6.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
Camera {
target: RenderTarget::Window(WindowRef::Entity(second_window)),
..default()
},
))
.id();
let node = Node {
position_type: PositionType::Absolute,
top: Val::Px(12.0),
left: Val::Px(12.0),
..default()
};
commands
.spawn((
node.clone(),
// Since we are using multiple cameras, we need to specify which camera UI should be rendered to
UiTargetCamera(first_window_camera),
))
.with_child((Text::new("First window"), TextShadow::default()));
commands
.spawn((node, UiTargetCamera(second_window_camera)))
.with_child((Text::new("Second window"), TextShadow::default()));
}