Skip to content

Commit

Permalink
Merge pull request #16 from dtcristo/bevy-0.10
Browse files Browse the repository at this point in the history
Update to bevy 0.10
  • Loading branch information
dtcristo authored Mar 29, 2023
2 parents a9589d8 + b8ac2b7 commit fe44070
Show file tree
Hide file tree
Showing 5 changed files with 263 additions and 134 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,30 @@

## [Unreleased]

### Added

- Added support support for multiple windows. Made possible by the move from `PixelsResource` to
`PixelsWrapper` described below.
- Added `multiple_windows` example demonstrating support for multiple windows.
- Added `scale_factor` option to control scale factor between logical window size and buffer size
when using `auto_resize_buffer`.
- Added `auto_resize_buffer` option to control automatic resizing of the buffer when the window
changes.
- Added `auto_resize_surface` option to control automatic resizing of the surface when the window
changes.

### Changed

- Updated `bevy` to 0.10.
- Updated `pixels` to 0.12.
- 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.

## [0.8.0] - 2022-12-20

Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ wayland = ["bevy/wayland"]
x11 = ["bevy/x11"]

[dependencies]
bevy = { version = "0.9", default_features = false, features = ["bevy_winit"] }
bevy = { version = "0.10", default_features = false, features = ["bevy_winit"] }
pixels = "0.12"

[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand Down
104 changes: 66 additions & 38 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use bevy::{
app::AppExit,
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
prelude::*,
window::WindowResizeConstraints,
window::{WindowResizeConstraints, WindowResolution},
};
use bevy_pixels::prelude::*;
use rand::prelude::*;

const WIDTH: u32 = 320;
const HEIGHT: u32 = 240;
const INITIAL_WIDTH: u32 = 320;
const INITIAL_HEIGHT: u32 = 240;
const SCALE_FACTOR: f32 = 2.0;

#[derive(Bundle, Debug)]
struct ObjectBundle {
Expand Down Expand Up @@ -42,36 +42,44 @@ struct Color(u8, u8, u8, u8);
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
window: WindowDescriptor {
primary_window: Some(Window {
title: "Hello Bevy Pixels".to_string(),
width: WIDTH as f32,
height: HEIGHT as f32,
resolution: WindowResolution::new(
INITIAL_WIDTH as f32 * SCALE_FACTOR,
INITIAL_HEIGHT as f32 * SCALE_FACTOR,
),
resize_constraints: WindowResizeConstraints {
min_width: WIDTH as f32,
min_height: HEIGHT as f32,
min_width: INITIAL_WIDTH as f32 * SCALE_FACTOR,
min_height: INITIAL_HEIGHT as f32 * SCALE_FACTOR,
..default()
},
fit_canvas_to_parent: true,
..default()
},
}),
..default()
}))
.add_plugin(PixelsPlugin {
width: WIDTH,
height: HEIGHT,
..default()
primary_window: Some(PixelsOptions {
width: INITIAL_WIDTH,
height: INITIAL_HEIGHT,
scale_factor: SCALE_FACTOR,
..default()
}),
})
.add_plugin(FrameTimeDiagnosticsPlugin::default())
.add_plugin(LogDiagnosticsPlugin::default())
.add_startup_system(setup)
.add_system(bounce)
.add_system(movement.after(bounce))
.add_system(exit_on_escape)
.add_system_to_stage(PixelsStage::Draw, draw_background)
.add_system_to_stage(PixelsStage::Draw, draw_objects.after(draw_background))
.add_system(bevy::window::close_on_esc)
.add_systems((bounce, movement).chain().in_set(PixelsSet::Update))
.add_systems(
(draw_background, draw_objects)
.chain()
.in_set(PixelsSet::Draw),
)
.run();
}

/// Spawn object.
fn setup(mut commands: Commands) {
let box_object = ObjectBundle {
position: Position { x: 24, y: 16 },
Expand All @@ -85,14 +93,28 @@ fn setup(mut commands: Commands) {
commands.spawn(box_object);
}

fn bounce(mut query: Query<(&Position, &mut Velocity, &Size, &mut Color)>) {
for (position, mut velocity, size, mut color) in query.iter_mut() {
/// Bounce object off edges of buffer.
fn bounce(
options_query: Query<&PixelsOptions>,
mut query: Query<(&Position, &mut Velocity, &Size, &mut Color)>,
) {
let Ok(options) = options_query.get_single() else { return };

for (position, mut velocity, size, mut color) in &mut query {
let mut bounce = false;
if position.x == 0 || position.x + size.width > WIDTH {
if position.x == 0 && velocity.x < 0 {
velocity.x *= -1;
bounce = true;
}
if position.x + size.width == options.width && velocity.x > 0 {
velocity.x *= -1;
bounce = true;
}
if position.y == 0 || position.y + size.height > HEIGHT {
if position.y == 0 && velocity.y < 0 {
velocity.y *= -1;
bounce = true;
}
if position.y + size.height == options.height && velocity.y > 0 {
velocity.y *= -1;
bounce = true;
}
Expand All @@ -104,37 +126,43 @@ fn bounce(mut query: Query<(&Position, &mut Velocity, &Size, &mut Color)>) {
}
}

fn movement(mut query: Query<(&mut Position, &Velocity)>) {
for (mut position, velocity) in query.iter_mut() {
position.x = (position.x as i16 + velocity.x) as u32;
position.y = (position.y as i16 + velocity.y) as u32;
}
}
/// Move object based on current velocity.
fn movement(
options_query: Query<&PixelsOptions>,
mut query: Query<(&mut Position, &Velocity, &Size)>,
) {
let Ok(options) = options_query.get_single() else { return };

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

fn draw_background(mut pixels_resource: ResMut<PixelsResource>) {
let frame = pixels_resource.pixels.frame_mut();
/// Draw solid background to buffer.
fn draw_background(mut wrapper_query: Query<&mut PixelsWrapper>) {
let Ok(mut wrapper) = wrapper_query.get_single_mut() else { return };
let frame = wrapper.pixels.frame_mut();

frame.copy_from_slice(&[0x48, 0xb2, 0xe8, 0xff].repeat(frame.len() / 4));
}

/// Draw objects to buffer.
fn draw_objects(
mut pixels_resource: ResMut<PixelsResource>,
mut wrapper_query: Query<(&mut PixelsWrapper, &PixelsOptions)>,
query: Query<(&Position, &Size, &Color)>,
) {
let frame = pixels_resource.pixels.frame_mut();
let frame_width_bytes = (WIDTH * 4) as usize;
let Ok((mut wrapper, options)) = wrapper_query.get_single_mut() else { return };
let frame = wrapper.pixels.frame_mut();
let frame_width_bytes = (options.width * 4) as usize;

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

for y in position.y..(position.y + size.height - 1) {
for y in position.y..(position.y + size.height) {
let y_offset = y as usize * frame_width_bytes;
let i = y_offset + x_offset;
let j = i + width_bytes;
Expand Down
27 changes: 27 additions & 0 deletions examples/multiple_windows.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use bevy::prelude::*;
use bevy_pixels::prelude::*;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(PixelsPlugin::default())
.add_startup_system(setup)
.add_system(bevy::window::close_on_esc)
.add_system(draw.in_set(PixelsSet::Draw))
.run();
}

/// Spawn two more windows in addition to the primary window that comes by default.
fn setup(mut commands: Commands) {
commands.spawn((Window::default(), PixelsOptions::default()));
commands.spawn((Window::default(), PixelsOptions::default()));
}

/// Draw solid background to each window's buffer.
fn draw(mut wrapper_query: Query<&mut PixelsWrapper>) {
for mut wrapper in &mut wrapper_query {
let frame = wrapper.pixels.frame_mut();

frame.copy_from_slice(&[0x48, 0xb2, 0xe8, 0xff].repeat(frame.len() / 4));
}
}
Loading

0 comments on commit fe44070

Please sign in to comment.