forked from vladbat00/bevy_egui
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtwo_windows.rs
179 lines (161 loc) · 5.52 KB
/
two_windows.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
use bevy::{
core_pipeline::{draw_3d_graph, node, AlphaMask3d, Opaque3d, Transparent3d},
prelude::*,
render::{
camera::{ActiveCameras, ExtractedCameraNames},
render_graph::{Node, NodeRunError, RenderGraph, RenderGraphContext, SlotValue},
render_phase::RenderPhase,
renderer::RenderContext,
RenderApp, RenderStage,
},
window::{CreateWindow, WindowId},
};
use bevy_egui::{EguiContext, EguiPlugin};
use once_cell::sync::Lazy;
static SECOND_WINDOW_ID: Lazy<WindowId> = Lazy::new(WindowId::new);
const BEVY_TEXTURE_ID: u64 = 0;
fn main() {
let mut app = App::new();
app.add_plugins(DefaultPlugins)
.add_plugin(EguiPlugin)
.init_resource::<SharedUiState>()
.add_startup_system(load_assets)
.add_startup_system(create_new_window)
.add_system(ui_first_window)
.add_system(ui_second_window);
let render_app = app.sub_app_mut(RenderApp);
render_app.add_system_to_stage(RenderStage::Extract, extract_secondary_camera_phases);
let mut graph = render_app.world.get_resource_mut::<RenderGraph>().unwrap();
graph.add_node(SECONDARY_PASS_DRIVER, SecondaryCameraDriver);
graph
.add_node_edge(node::MAIN_PASS_DEPENDENCIES, SECONDARY_PASS_DRIVER)
.unwrap();
bevy_egui::setup_pipeline(
&mut graph,
bevy_egui::RenderGraphConfig {
window_id: *SECOND_WINDOW_ID,
egui_pass: SECONDARY_EGUI_PASS,
},
);
app.run();
}
fn extract_secondary_camera_phases(mut commands: Commands, active_cameras: Res<ActiveCameras>) {
if let Some(secondary) = active_cameras.get(SECONDARY_CAMERA_NAME) {
if let Some(entity) = secondary.entity {
commands.get_or_spawn(entity).insert_bundle((
RenderPhase::<Opaque3d>::default(),
RenderPhase::<AlphaMask3d>::default(),
RenderPhase::<Transparent3d>::default(),
));
}
}
}
const SECONDARY_CAMERA_NAME: &str = "Secondary";
const SECONDARY_PASS_DRIVER: &str = "secondary_pass_driver";
const SECONDARY_EGUI_PASS: &str = "secondary_egui_pass";
fn create_new_window(
mut create_window_events: EventWriter<CreateWindow>,
mut commands: Commands,
mut active_cameras: ResMut<ActiveCameras>,
) {
// sends out a "CreateWindow" event, which will be received by the windowing backend
create_window_events.send(CreateWindow {
id: *SECOND_WINDOW_ID,
descriptor: WindowDescriptor {
width: 800.,
height: 600.,
vsync: false,
title: "Second window".to_string(),
..Default::default()
},
});
// second window camera
commands.spawn_bundle(PerspectiveCameraBundle {
camera: Camera {
window: *SECOND_WINDOW_ID,
name: Some(SECONDARY_CAMERA_NAME.into()),
..Default::default()
},
transform: Transform::from_xyz(6.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
..Default::default()
});
active_cameras.add(SECONDARY_CAMERA_NAME);
}
fn load_assets(mut egui_context: ResMut<EguiContext>, assets: Res<AssetServer>) {
let texture_handle = assets.load("icon.png");
egui_context.set_egui_texture(BEVY_TEXTURE_ID, texture_handle);
}
struct SecondaryCameraDriver;
impl Node for SecondaryCameraDriver {
fn run(
&self,
graph: &mut RenderGraphContext,
_render_context: &mut RenderContext,
world: &World,
) -> Result<(), NodeRunError> {
let extracted_cameras = world.get_resource::<ExtractedCameraNames>().unwrap();
if let Some(camera_3d) = extracted_cameras.entities.get(SECONDARY_CAMERA_NAME) {
graph.run_sub_graph(
crate::draw_3d_graph::NAME,
vec![SlotValue::Entity(*camera_3d)],
)?;
}
Ok(())
}
}
#[derive(Default)]
struct UiState {
input: String,
}
#[derive(Default)]
struct SharedUiState {
shared_input: String,
}
fn ui_first_window(
mut egui_context: ResMut<EguiContext>,
mut ui_state: Local<UiState>,
mut shared_ui_state: ResMut<SharedUiState>,
) {
egui::Window::new("First Window")
.vscroll(true)
.show(egui_context.ctx_mut(), |ui| {
ui.horizontal(|ui| {
ui.label("Write something: ");
ui.text_edit_singleline(&mut ui_state.input);
});
ui.horizontal(|ui| {
ui.label("Shared input: ");
ui.text_edit_singleline(&mut shared_ui_state.shared_input);
});
ui.add(egui::widgets::Image::new(
egui::TextureId::User(BEVY_TEXTURE_ID),
[256.0, 256.0],
));
});
}
fn ui_second_window(
mut egui_context: ResMut<EguiContext>,
mut ui_state: Local<UiState>,
mut shared_ui_state: ResMut<SharedUiState>,
) {
let ctx = match egui_context.try_ctx_for_window_mut(*SECOND_WINDOW_ID) {
Some(ctx) => ctx,
None => return,
};
egui::Window::new("Second Window")
.vscroll(true)
.show(ctx, |ui| {
ui.horizontal(|ui| {
ui.label("Write something else: ");
ui.text_edit_singleline(&mut ui_state.input);
});
ui.horizontal(|ui| {
ui.label("Shared input: ");
ui.text_edit_singleline(&mut shared_ui_state.shared_input);
});
ui.add(egui::widgets::Image::new(
egui::TextureId::User(BEVY_TEXTURE_ID),
[256.0, 256.0],
));
});
}