Skip to main content

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(WorldAssetRoot(
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            RenderTarget::Window(WindowRef::Entity(second_window)),
44        ))
45        .id();
46
47    let node = Node {
48        position_type: PositionType::Absolute,
49        top: px(12),
50        left: px(12),
51        ..default()
52    };
53
54    commands
55        .spawn((
56            node.clone(),
57            // Since we are using multiple cameras, we need to specify which camera UI should be rendered to
58            UiTargetCamera(first_window_camera),
59        ))
60        .with_child((Text::new("First window"), TextShadow::default()));
61
62    commands
63        .spawn((node, UiTargetCamera(second_window_camera)))
64        .with_child((Text::new("Second window"), TextShadow::default()));
65}