multiple_windows/
multiple_windows.rs

1//! Uses two windows to visualize a 3D model from different angles.
2
3use bevy::{camera::RenderTarget, prelude::*, window::WindowRef};
4
5fn main() {
6    App::new()
7        // By default, a primary window gets spawned by `WindowPlugin`, contained in `DefaultPlugins`
8        .add_plugins(DefaultPlugins)
9        .add_systems(Startup, setup_scene)
10        .run();
11}
12
13fn setup_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
14    // add entities to the world
15    commands.spawn(SceneRoot(
16        asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/torus/torus.gltf")),
17    ));
18    // light
19    commands.spawn((
20        DirectionalLight::default(),
21        Transform::from_xyz(3.0, 3.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y),
22    ));
23
24    let first_window_camera = commands
25        .spawn((
26            Camera3d::default(),
27            Transform::from_xyz(0.0, 0.0, 6.0).looking_at(Vec3::ZERO, Vec3::Y),
28        ))
29        .id();
30
31    // Spawn a second window
32    let second_window = commands
33        .spawn(Window {
34            title: "Second window".to_owned(),
35            ..default()
36        })
37        .id();
38
39    let second_window_camera = commands
40        .spawn((
41            Camera3d::default(),
42            Transform::from_xyz(6.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
43            Camera {
44                target: RenderTarget::Window(WindowRef::Entity(second_window)),
45                ..default()
46            },
47        ))
48        .id();
49
50    let node = Node {
51        position_type: PositionType::Absolute,
52        top: px(12),
53        left: px(12),
54        ..default()
55    };
56
57    commands
58        .spawn((
59            node.clone(),
60            // Since we are using multiple cameras, we need to specify which camera UI should be rendered to
61            UiTargetCamera(first_window_camera),
62        ))
63        .with_child((Text::new("First window"), TextShadow::default()));
64
65    commands
66        .spawn((node, UiTargetCamera(second_window_camera)))
67        .with_child((Text::new("Second window"), TextShadow::default()));
68}