Skip to content

Commit

Permalink
Merge pull request #26 from aevyrie/v0.8.0
Browse files Browse the repository at this point in the history
Update for bevy 0.9
  • Loading branch information
aevyrie authored Nov 14, 2022
2 parents 337695a + 90ed15c commit 2bf2a63
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 45 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bevy_framepace"
version = "0.7.0"
version = "0.8.0"
edition = "2021"
resolver = "2"
description = "Frame pacing and frame limiting for Bevy"
Expand All @@ -11,7 +11,7 @@ documentation = "https://docs.rs/bevy_framepace"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bevy = { version = "0.8", default-features = false, features = [
bevy = { version = "0.9", default-features = false, features = [
"bevy_render",
"bevy_winit",
] }
Expand All @@ -21,8 +21,8 @@ default = ["x11"]
x11 = ["bevy/x11"]

[dev-dependencies]
bevy_mod_picking = "0.9"
bevy = { version = "0.8", default-features = false, features = [
bevy_mod_picking = "0.10"
bevy = { version = "0.9", default-features = false, features = [
"bevy_ui",
"bevy_text",
"bevy_core_pipeline",
Expand Down
40 changes: 26 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
[![crates.io](https://img.shields.io/crates/v/bevy_framepace)](https://crates.io/crates/bevy_framepace)
[![docs.rs](https://docs.rs/bevy_framepace/badge.svg)](https://docs.rs/bevy_framepace)
[![CI](https://github.com/aevyrie/bevy_framepace/workflows/CI/badge.svg?branch=main)](https://github.com/aevyrie/bevy_framepace/actions?query=workflow%3A%22CI%22+branch%3Amain)
[![Bevy tracking](https://img.shields.io/badge/Bevy%20tracking-main-lightblue)](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md#main-branch-tracking)
[![Bevy](https://img.shields.io/badge/Bevy%20tracking-main-lightblue)](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md#main-branch-tracking)

<video src = "https://user-images.githubusercontent.com/2632925/164378172-faa136d5-e78f-4328-9962-afbf410753ce.mp4"></video>
<video src =
"https://user-images.githubusercontent.com/2632925/164378172-faa136d5-e78f-4328-9962-afbf410753ce.mp4"></video>

</div>

Expand All @@ -23,10 +24,11 @@ app.add_plugin(bevy_framepace::FramepacePlugin::default())

By default, the plugin will automatically measure your framerate and use this for framepacing.

You can adjust the framerate limit when adding the plugin, or at runtime by modifying the`FramepacePlugin` resource. For example, to set the framerate limit to 30fps:
You can adjust the framerate limit at runtime by modifying the`FramepaceSettings` resource. For
example, to set the framerate limit to 30fps:

```rs
settings.framerate_limit = FramerateLimit::Manual(30),
settings.limiter = Limiter::from_framerate(30.0),
```

See `demo.rs` in the examples folder, or run with:
Expand All @@ -36,7 +38,14 @@ cargo run --release --example demo

## How it works

The plugin works by recording how long it takes to render each frame, and sleeping the main thread until the desired frametime is reached. This ensures the next frame isn't started until the very last moment, delaying the event loop from restarting. By delaying the event loop, and thus input collection, this reduces motion-to-photon latency by moving reading input closer to rendering the frame.
The plugin works by recording how long it takes to render each frame, and sleeping the main thread
until the desired frametime is reached. This ensures the next frame isn't started until the very
last moment, delaying the event loop from restarting. By delaying the event loop, and thus input
collection, this reduces motion-to-photon latency by moving reading input closer to rendering the
frame.

The `spin_sleep` dependency is needed for precise sleep times. The sleep function in the standard
library is not accurate enough for this application, especially on Windows.


## Bevy Version Support
Expand All @@ -45,24 +54,27 @@ I intend to track the `main` branch of Bevy. PRs supporting this are welcome!

| bevy | bevy_framepace |
| ---- | -------------- |
| 0.9 | 0.7 |
| 0.8 | 0.5, 0.6 |
| 0.7 | 0.4 |
| 0.6 | 0.3 |


## License

`bevy_framepace` is free, open source and permissively licensed! Except where noted (below and/or in individual files), all code in this repository is dual-licensed under either:
`bevy_framepace` is free, open source and permissively licensed! Except where noted (below and/or in
individual files), all code in this repository is dual-licensed under either:

* MIT License ([LICENSE-MIT](LICENSE-MIT) or [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT))
* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0))
* MIT License ([LICENSE-MIT](LICENSE-MIT) or
[http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT))
* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0))

at your option. This means you can select the license you prefer! This dual-licensing approach is the de-facto standard in the Rust ecosystem and there are very good reasons to include both.
at your option. This means you can select the license you prefer! This dual-licensing approach is
the de-facto standard in the Rust ecosystem and there are very good reasons to include both.

### Your contributions

Unless you explicitly state otherwise,
any contribution intentionally submitted for inclusion in the work by you,
as defined in the Apache-2.0 license,
shall be dual licensed as above,
without any additional terms or conditions.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the
work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.
Binary file added assets/fonts/FiraMono-Medium.ttf
Binary file not shown.
Binary file removed assets/fonts/FiraSans-Bold.ttf
Binary file not shown.
37 changes: 20 additions & 17 deletions examples/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn toggle_plugin(mut settings: ResMut<FramepaceSettings>, input: Res<Input<KeyCo
}

fn update_ui(mut text: Query<&mut Text, With<EnableText>>, settings: Res<FramepaceSettings>) {
text.single_mut().sections[1].value = format!("{:?}", settings.limiter);
text.single_mut().sections[1].value = format!("{}", settings.limiter);
}

/// set up the scene
Expand All @@ -50,34 +50,36 @@ fn setup(
.get_primary_mut()
.unwrap()
.set_cursor_icon(CursorIcon::Crosshair);
commands
.spawn_bundle(PbrBundle {
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 25.0 })),
material: materials.add(Color::GRAY.into()),
material: materials.add(Color::BLACK.into()),
..Default::default()
})
.insert_bundle(PickableBundle::default());
commands
.spawn_bundle(Camera3dBundle {
},
PickableBundle::default(),
));
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(0.0, 10.0, 0.0).looking_at(Vec3::ZERO, Vec3::Z),
projection: Projection::Orthographic(OrthographicProjection {
scale: 0.01,
..Default::default()
}),
..Default::default()
})
.insert_bundle(PickingCameraBundle::default());
},
PickingCameraBundle::default(),
));
// UI
let font = asset_server.load("fonts/FiraSans-Bold.ttf");
let font = asset_server.load("fonts/FiraMono-Medium.ttf");
let style = TextStyle {
font: font,
font,
font_size: 40.0,
color: Color::WHITE,
};
commands
.spawn_bundle(TextBundle {
commands.spawn((
TextBundle {
style: Style {
align_self: AlignSelf::FlexEnd,
align_self: AlignSelf::FlexStart,
..default()
},
text: Text {
Expand All @@ -99,6 +101,7 @@ fn setup(
..default()
},
..default()
})
.insert(EnableText);
},
EnableText,
));
}
29 changes: 19 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ impl Plugin for FramepacePlugin {
.add_system_to_stage(
RenderStage::Cleanup,
// We need this system to run at the end, immediately before the event loop restarts
framerate_limiter.exclusive_system().at_end(),
framerate_limiter.at_end(),
);
}
}

/// Framepacing plugin configuration.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Resource)]
pub struct FramepaceSettings {
/// Configures the framerate limiting strategy.
pub limiter: Limiter,
Expand Down Expand Up @@ -109,10 +109,21 @@ impl Limiter {
}
}

#[derive(Debug, Default, Clone)]
impl std::fmt::Display for Limiter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let output = match self {
Limiter::Auto => "Auto".into(),
Limiter::Manual(t) => format!("{:.2} fps", 1.0 / t.as_secs_f32()),
Limiter::Off => "Off".into(),
};
write!(f, "{}", output)
}
}

#[derive(Debug, Default, Clone, Resource)]
struct FrametimeLimit(Duration);

#[derive(Debug)]
#[derive(Debug, Resource)]
struct FrameTimer {
render_end: Instant,
}
Expand Down Expand Up @@ -155,11 +166,9 @@ fn detect_frametime(winit: NonSend<WinitWindows>, windows: Res<Windows>) -> Opti
let monitor = winit
.get_window(windows.get_primary()?.id())?
.current_monitor()?;
// We need to subtract 0.5 here because winit only reports framerate to the nearest integer. To
// prevent frames building up, adding latency, we need to use the most conservative possible
// refresh rate that could round up to the integer value reported by winit.
let best_framerate = bevy::winit::get_best_videomode(&monitor).refresh_rate() as f64 - 0.5;
let best_frametime = Duration::from_secs_f64(1.0 / best_framerate);
let best_framerate_mhz =
bevy::winit::get_best_videomode(&monitor).refresh_rate_millihertz() as f32;
let best_frametime = Duration::from_secs_f32(1000.0 / best_framerate_mhz);
Some(best_frametime)
}

Expand All @@ -175,7 +184,7 @@ fn extract_resources(
}

/// Holds frame time measurements for framepacing diagnostics
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Resource)]
pub struct FramePaceStats {
oversleep: Arc<Mutex<VecDeque<Duration>>>,
frametime: Arc<Mutex<Duration>>,
Expand Down

0 comments on commit 2bf2a63

Please sign in to comment.