Skip to content

Commit ed9d45f

Browse files
committed
Add an example 'showcasing' using multiple windows (#3367)
# Objective - The multiple windows example which was viciously murdered in #3175. - cart asked me to ## Solution - Rework the example to work on pipelined-rendering, based on the work from #2898
1 parent b5a0453 commit ed9d45f

File tree

4 files changed

+118
-2
lines changed

4 files changed

+118
-2
lines changed

Cargo.toml

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ default = [
2525
"hdr",
2626
"mp3",
2727
"x11",
28-
"filesystem_watcher"
28+
"filesystem_watcher",
2929
]
3030

3131
# Force dynamic linking, which improves iterative compile times
@@ -441,6 +441,10 @@ path = "examples/ui/ui.rs"
441441
name = "clear_color"
442442
path = "examples/window/clear_color.rs"
443443

444+
[[example]]
445+
name = "multiple_windows"
446+
path = "examples/window/multiple_windows.rs"
447+
444448
[[example]]
445449
name = "scale_factor_override"
446450
path = "examples/window/scale_factor_override.rs"

crates/bevy_render/src/camera/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ fn extract_cameras(
8282
if let Some((entity, camera, transform, visible_entities)) =
8383
camera.entity.and_then(|e| query.get(e).ok())
8484
{
85-
entities.insert(name.clone(), entity);
8685
if let Some(window) = windows.get(camera.window) {
86+
entities.insert(name.clone(), entity);
8787
commands.get_or_spawn(entity).insert_bundle((
8888
ExtractedCamera {
8989
window_id: camera.window,

examples/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ Example | File | Description
243243
Example | File | Description
244244
--- | --- | ---
245245
`clear_color` | [`window/clear_color.rs`](./window/clear_color.rs) | Creates a solid color window
246+
`multiple_windows` | [`window/multiple_windows.rs`](./window/multiple_windows.rs) | Demonstrates creating multiple windows, and rendering to them
246247
`scale_factor_override` | [`window/scale_factor_override.rs`](./window/scale_factor_override.rs) | Illustrates how to customize the default window settings
247248
`transparent_window` | [`window/transparent_window.rs`](./window/transparent_window.rs) | Illustrates making the window transparent and hiding the window decoration
248249
`window_settings` | [`window/window_settings.rs`](./window/window_settings.rs) | Demonstrates customizing default window settings

examples/window/multiple_windows.rs

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use bevy::{
2+
core_pipeline::{draw_3d_graph, node, AlphaMask3d, Opaque3d, Transparent3d},
3+
prelude::*,
4+
render::{
5+
camera::{ActiveCameras, ExtractedCameraNames},
6+
render_graph::{Node, NodeRunError, RenderGraph, RenderGraphContext, SlotValue},
7+
render_phase::RenderPhase,
8+
renderer::RenderContext,
9+
RenderApp, RenderStage,
10+
},
11+
window::{CreateWindow, WindowId},
12+
};
13+
14+
/// This example creates a second window and draws a mesh from two different cameras, one in each window
15+
fn main() {
16+
let mut app = App::new();
17+
app.add_plugins(DefaultPlugins)
18+
.add_startup_system(setup)
19+
.add_startup_system(create_new_window);
20+
21+
let render_app = app.sub_app(RenderApp);
22+
render_app.add_system_to_stage(RenderStage::Extract, extract_secondary_camera_phases);
23+
let mut graph = render_app.world.get_resource_mut::<RenderGraph>().unwrap();
24+
graph.add_node(SECONDARY_PASS_DRIVER, SecondaryCameraDriver);
25+
graph
26+
.add_node_edge(node::MAIN_PASS_DEPENDENCIES, SECONDARY_PASS_DRIVER)
27+
.unwrap();
28+
app.run();
29+
}
30+
31+
fn extract_secondary_camera_phases(mut commands: Commands, active_cameras: Res<ActiveCameras>) {
32+
if let Some(secondary) = active_cameras.get(SECONDARY_CAMERA_NAME) {
33+
if let Some(entity) = secondary.entity {
34+
commands.get_or_spawn(entity).insert_bundle((
35+
RenderPhase::<Opaque3d>::default(),
36+
RenderPhase::<AlphaMask3d>::default(),
37+
RenderPhase::<Transparent3d>::default(),
38+
));
39+
}
40+
}
41+
}
42+
43+
const SECONDARY_CAMERA_NAME: &str = "Secondary";
44+
const SECONDARY_PASS_DRIVER: &str = "secondary_pass_driver";
45+
46+
fn create_new_window(
47+
mut create_window_events: EventWriter<CreateWindow>,
48+
49+
mut commands: Commands,
50+
mut active_cameras: ResMut<ActiveCameras>,
51+
) {
52+
let window_id = WindowId::new();
53+
54+
// sends out a "CreateWindow" event, which will be received by the windowing backend
55+
create_window_events.send(CreateWindow {
56+
id: window_id,
57+
descriptor: WindowDescriptor {
58+
width: 800.,
59+
height: 600.,
60+
vsync: false,
61+
title: "Second window".to_string(),
62+
..Default::default()
63+
},
64+
});
65+
// second window camera
66+
commands.spawn_bundle(PerspectiveCameraBundle {
67+
camera: Camera {
68+
window: window_id,
69+
name: Some(SECONDARY_CAMERA_NAME.into()),
70+
..Default::default()
71+
},
72+
transform: Transform::from_xyz(6.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
73+
..Default::default()
74+
});
75+
76+
active_cameras.add(SECONDARY_CAMERA_NAME);
77+
}
78+
79+
struct SecondaryCameraDriver;
80+
impl Node for SecondaryCameraDriver {
81+
fn run(
82+
&self,
83+
graph: &mut RenderGraphContext,
84+
_render_context: &mut RenderContext,
85+
world: &World,
86+
) -> Result<(), NodeRunError> {
87+
let extracted_cameras = world.get_resource::<ExtractedCameraNames>().unwrap();
88+
if let Some(camera_3d) = extracted_cameras.entities.get(SECONDARY_CAMERA_NAME) {
89+
graph.run_sub_graph(
90+
crate::draw_3d_graph::NAME,
91+
vec![SlotValue::Entity(*camera_3d)],
92+
)?;
93+
}
94+
Ok(())
95+
}
96+
}
97+
98+
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
99+
// add entities to the world
100+
commands.spawn_scene(asset_server.load("models/monkey/Monkey.gltf#Scene0"));
101+
// light
102+
commands.spawn_bundle(PointLightBundle {
103+
transform: Transform::from_xyz(4.0, 5.0, 4.0),
104+
..Default::default()
105+
});
106+
// main camera
107+
commands.spawn_bundle(PerspectiveCameraBundle {
108+
transform: Transform::from_xyz(0.0, 0.0, 6.0).looking_at(Vec3::ZERO, Vec3::Y),
109+
..Default::default()
110+
});
111+
}

0 commit comments

Comments
 (0)