Skip to content

Commit b8ac2b7

Browse files
committed
Major bevy 0.10 changes
- Adds support support for multiple windows. Made possible by the move from `PixelsResource` to `PixelsWrapper` described below. - Adds `multiple_windows` example demonstrating support for multiple windows. - Adds `scale_factor` option to control scale factor between logical window size and buffer size when using `auto_resize_buffer`. - Adds `auto_resize_buffer` option to control automatic resizing of the buffer when the window changes. - Adds `auto_resize_surface` option to control automatic resizing of the surface when the window changes. - Configuration of buffer size has been moved from `PixelsPlugin` to `PixelsOptions`. - Primary window buffer is created by providing `Some(PixelsOptions { ... })` to the `primary_window` when creating `PixelsPlugin`. This works the same was as Bevy's own configuration of primary window in the `WindowPlugin`. - Resouce `PixelsResource` has been replaced with `PixelsWrapper` component that is automatically added to `Window` entities with the `PixelsOptions` component. - Diagnostic `PixelsPlugin::RENDER_TIME` is now recorded in miliseconds instead of seconds. - Updated `minimal` example to demonstrate `auto_resize_buffer` feature.
1 parent 22f8474 commit b8ac2b7

File tree

4 files changed

+251
-108
lines changed

4 files changed

+251
-108
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,30 @@
22

33
## [Unreleased]
44

5+
### Added
6+
7+
- Added support support for multiple windows. Made possible by the move from `PixelsResource` to
8+
`PixelsWrapper` described below.
9+
- Added `multiple_windows` example demonstrating support for multiple windows.
10+
- Added `scale_factor` option to control scale factor between logical window size and buffer size
11+
when using `auto_resize_buffer`.
12+
- Added `auto_resize_buffer` option to control automatic resizing of the buffer when the window
13+
changes.
14+
- Added `auto_resize_surface` option to control automatic resizing of the surface when the window
15+
changes.
16+
517
### Changed
618

719
- Updated `bevy` to 0.10.
820
- Updated `pixels` to 0.12.
21+
- Configuration of buffer size has been moved from `PixelsPlugin` to `PixelsOptions`.
22+
- Primary window buffer is created by providing `Some(PixelsOptions { ... })` to the
23+
`primary_window` when creating `PixelsPlugin`. This works the same was as Bevy's own configuration
24+
of primary window in the `WindowPlugin`.
25+
- Resouce `PixelsResource` has been replaced with `PixelsWrapper` component that is automatically
26+
added to `Window` entities with the `PixelsOptions` component.
27+
- Diagnostic `PixelsPlugin::RENDER_TIME` is now recorded in miliseconds instead of seconds.
28+
- Updated `minimal` example to demonstrate `auto_resize_buffer` feature.
929

1030
## [0.8.0] - 2022-12-20
1131

examples/minimal.rs

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use bevy::{
2-
app::AppExit,
32
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
43
prelude::*,
54
window::{WindowResizeConstraints, WindowResolution},
65
};
76
use bevy_pixels::prelude::*;
87
use rand::prelude::*;
98

10-
const WIDTH: u32 = 320;
11-
const HEIGHT: u32 = 240;
9+
const INITIAL_WIDTH: u32 = 320;
10+
const INITIAL_HEIGHT: u32 = 240;
11+
const SCALE_FACTOR: f32 = 2.0;
1212

1313
#[derive(Bundle, Debug)]
1414
struct ObjectBundle {
@@ -44,10 +44,13 @@ fn main() {
4444
.add_plugins(DefaultPlugins.set(WindowPlugin {
4545
primary_window: Some(Window {
4646
title: "Hello Bevy Pixels".to_string(),
47-
resolution: WindowResolution::new(WIDTH as f32, HEIGHT as f32),
47+
resolution: WindowResolution::new(
48+
INITIAL_WIDTH as f32 * SCALE_FACTOR,
49+
INITIAL_HEIGHT as f32 * SCALE_FACTOR,
50+
),
4851
resize_constraints: WindowResizeConstraints {
49-
min_width: WIDTH as f32,
50-
min_height: HEIGHT as f32,
52+
min_width: INITIAL_WIDTH as f32 * SCALE_FACTOR,
53+
min_height: INITIAL_HEIGHT as f32 * SCALE_FACTOR,
5154
..default()
5255
},
5356
fit_canvas_to_parent: true,
@@ -56,21 +59,27 @@ fn main() {
5659
..default()
5760
}))
5861
.add_plugin(PixelsPlugin {
59-
width: WIDTH,
60-
height: HEIGHT,
61-
..default()
62+
primary_window: Some(PixelsOptions {
63+
width: INITIAL_WIDTH,
64+
height: INITIAL_HEIGHT,
65+
scale_factor: SCALE_FACTOR,
66+
..default()
67+
}),
6268
})
6369
.add_plugin(FrameTimeDiagnosticsPlugin::default())
6470
.add_plugin(LogDiagnosticsPlugin::default())
6571
.add_startup_system(setup)
66-
.add_system(bounce)
67-
.add_system(movement.after(bounce))
68-
.add_system(exit_on_escape)
69-
.add_system(draw_background.in_set(PixelsSet::Draw))
70-
.add_system(draw_objects.in_set(PixelsSet::Draw).after(draw_background))
72+
.add_system(bevy::window::close_on_esc)
73+
.add_systems((bounce, movement).chain().in_set(PixelsSet::Update))
74+
.add_systems(
75+
(draw_background, draw_objects)
76+
.chain()
77+
.in_set(PixelsSet::Draw),
78+
)
7179
.run();
7280
}
7381

82+
/// Spawn object.
7483
fn setup(mut commands: Commands) {
7584
let box_object = ObjectBundle {
7685
position: Position { x: 24, y: 16 },
@@ -84,14 +93,28 @@ fn setup(mut commands: Commands) {
8493
commands.spawn(box_object);
8594
}
8695

87-
fn bounce(mut query: Query<(&Position, &mut Velocity, &Size, &mut Color)>) {
88-
for (position, mut velocity, size, mut color) in query.iter_mut() {
96+
/// Bounce object off edges of buffer.
97+
fn bounce(
98+
options_query: Query<&PixelsOptions>,
99+
mut query: Query<(&Position, &mut Velocity, &Size, &mut Color)>,
100+
) {
101+
let Ok(options) = options_query.get_single() else { return };
102+
103+
for (position, mut velocity, size, mut color) in &mut query {
89104
let mut bounce = false;
90-
if position.x == 0 || position.x + size.width > WIDTH {
105+
if position.x == 0 && velocity.x < 0 {
106+
velocity.x *= -1;
107+
bounce = true;
108+
}
109+
if position.x + size.width == options.width && velocity.x > 0 {
91110
velocity.x *= -1;
92111
bounce = true;
93112
}
94-
if position.y == 0 || position.y + size.height > HEIGHT {
113+
if position.y == 0 && velocity.y < 0 {
114+
velocity.y *= -1;
115+
bounce = true;
116+
}
117+
if position.y + size.height == options.height && velocity.y > 0 {
95118
velocity.y *= -1;
96119
bounce = true;
97120
}
@@ -103,37 +126,43 @@ fn bounce(mut query: Query<(&Position, &mut Velocity, &Size, &mut Color)>) {
103126
}
104127
}
105128

106-
fn movement(mut query: Query<(&mut Position, &Velocity)>) {
107-
for (mut position, velocity) in query.iter_mut() {
108-
position.x = (position.x as i16 + velocity.x) as u32;
109-
position.y = (position.y as i16 + velocity.y) as u32;
110-
}
111-
}
129+
/// Move object based on current velocity.
130+
fn movement(
131+
options_query: Query<&PixelsOptions>,
132+
mut query: Query<(&mut Position, &Velocity, &Size)>,
133+
) {
134+
let Ok(options) = options_query.get_single() else { return };
112135

113-
fn exit_on_escape(keyboard_input: Res<Input<KeyCode>>, mut app_exit_events: EventWriter<AppExit>) {
114-
if keyboard_input.just_pressed(KeyCode::Escape) {
115-
app_exit_events.send(AppExit);
136+
for (mut position, velocity, size) in &mut query {
137+
position.x = ((position.x as i16 + velocity.x) as u32).clamp(0, options.width - size.width);
138+
position.y =
139+
((position.y as i16 + velocity.y) as u32).clamp(0, options.height - size.height);
116140
}
117141
}
118142

119-
fn draw_background(mut pixels_resource: ResMut<PixelsResource>) {
120-
let frame = pixels_resource.pixels.frame_mut();
143+
/// Draw solid background to buffer.
144+
fn draw_background(mut wrapper_query: Query<&mut PixelsWrapper>) {
145+
let Ok(mut wrapper) = wrapper_query.get_single_mut() else { return };
146+
let frame = wrapper.pixels.frame_mut();
147+
121148
frame.copy_from_slice(&[0x48, 0xb2, 0xe8, 0xff].repeat(frame.len() / 4));
122149
}
123150

151+
/// Draw objects to buffer.
124152
fn draw_objects(
125-
mut pixels_resource: ResMut<PixelsResource>,
153+
mut wrapper_query: Query<(&mut PixelsWrapper, &PixelsOptions)>,
126154
query: Query<(&Position, &Size, &Color)>,
127155
) {
128-
let frame = pixels_resource.pixels.frame_mut();
129-
let frame_width_bytes = (WIDTH * 4) as usize;
156+
let Ok((mut wrapper, options)) = wrapper_query.get_single_mut() else { return };
157+
let frame = wrapper.pixels.frame_mut();
158+
let frame_width_bytes = (options.width * 4) as usize;
130159

131-
for (position, size, color) in query.iter() {
160+
for (position, size, color) in &query {
132161
let x_offset = (position.x * 4) as usize;
133162
let width_bytes = (size.width * 4) as usize;
134163
let object_row = &[color.0, color.1, color.2, color.3].repeat(size.width as usize);
135164

136-
for y in position.y..(position.y + size.height - 1) {
165+
for y in position.y..(position.y + size.height) {
137166
let y_offset = y as usize * frame_width_bytes;
138167
let i = y_offset + x_offset;
139168
let j = i + width_bytes;

examples/multiple_windows.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use bevy::prelude::*;
2+
use bevy_pixels::prelude::*;
3+
4+
fn main() {
5+
App::new()
6+
.add_plugins(DefaultPlugins)
7+
.add_plugin(PixelsPlugin::default())
8+
.add_startup_system(setup)
9+
.add_system(bevy::window::close_on_esc)
10+
.add_system(draw.in_set(PixelsSet::Draw))
11+
.run();
12+
}
13+
14+
/// Spawn two more windows in addition to the primary window that comes by default.
15+
fn setup(mut commands: Commands) {
16+
commands.spawn((Window::default(), PixelsOptions::default()));
17+
commands.spawn((Window::default(), PixelsOptions::default()));
18+
}
19+
20+
/// Draw solid background to each window's buffer.
21+
fn draw(mut wrapper_query: Query<&mut PixelsWrapper>) {
22+
for mut wrapper in &mut wrapper_query {
23+
let frame = wrapper.pixels.frame_mut();
24+
25+
frame.copy_from_slice(&[0x48, 0xb2, 0xe8, 0xff].repeat(frame.len() / 4));
26+
}
27+
}

0 commit comments

Comments
 (0)