Skip to content

Commit

Permalink
Automatically generate screenshots for all examples (emilk#2379)
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk authored Dec 4, 2022
1 parent b774159 commit 48666e1
Show file tree
Hide file tree
Showing 60 changed files with 206 additions and 30 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions crates/eframe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ puffin = ["dep:puffin", "egui_glow?/puffin", "egui-wgpu?/puffin"]
## Enable screen reader support (requires `ctx.options().screen_reader = true;`)
screen_reader = ["egui-winit/screen_reader", "tts"]

## If set, eframe will look for the env-var `EFRAME_SCREENSHOT_TO` and write a screenshot to that location, and then quit.
## This is used to generate images for the examples.
__screenshot = ["dep:image"]

## Use [`wgpu`](https://docs.rs/wgpu) for painting (via [`egui-wgpu`](https://github.com/emilk/egui/tree/master/crates/egui-wgpu)).
## This overrides the `glow` feature.
wgpu = ["dep:wgpu", "dep:egui-wgpu"]
Expand Down Expand Up @@ -89,6 +93,9 @@ directories-next = { version = "2", optional = true }
egui-wgpu = { version = "0.19.0", path = "../egui-wgpu", optional = true, features = [
"winit",
] }
image = { version = "0.24", optional = true, default-features = false, features = [
"png",
] }
puffin = { version = "0.14", optional = true }
wgpu = { version = "0.14", optional = true }

Expand Down
6 changes: 6 additions & 0 deletions crates/eframe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ mod native;
pub fn run_native(app_name: &str, native_options: NativeOptions, app_creator: AppCreator) {
let renderer = native_options.renderer;

#[cfg(not(feature = "__screenshot"))]
assert!(
std::env::var("EFRAME_SCREENSHOT_TO").is_err(),
"EFRAME_SCREENSHOT_TO found without compiling with the '__screenshot' feature"
);

match renderer {
#[cfg(feature = "glow")]
Renderer::Glow => {
Expand Down
41 changes: 36 additions & 5 deletions crates/eframe/src/native/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
})
}

fn centere_window_pos(
fn center_window_pos(
monitor: Option<winit::monitor::MonitorHandle>,
native_options: &mut epi::NativeOptions,
) {
Expand Down Expand Up @@ -308,6 +308,8 @@ mod glow_integration {
// suspends and resumes.
app_creator: Option<epi::AppCreator>,
is_focused: bool,

frame_nr: u64,
}

impl GlowWinitApp {
Expand All @@ -324,6 +326,7 @@ mod glow_integration {
running: None,
app_creator: Some(app_creator),
is_focused: true,
frame_nr: 0,
}
}

Expand Down Expand Up @@ -517,6 +520,26 @@ mod glow_integration {

integration.post_present(window);

#[cfg(feature = "__screenshot")]
// give it time to settle:
if self.frame_nr == 2 {
if let Ok(path) = std::env::var("EFRAME_SCREENSHOT_TO") {
assert!(
path.ends_with(".png"),
"Expected EFRAME_SCREENSHOT_TO to end with '.png', got {path:?}"
);
let [w, h] = screen_size_in_pixels;
let pixels = painter.read_screen_rgba(screen_size_in_pixels);
let image = image::RgbaImage::from_vec(w, h, pixels).unwrap();
let image = image::imageops::flip_vertical(&image);
image.save(&path).unwrap_or_else(|err| {
panic!("Failed to save screenshot to {path:?}: {err}");
});
eprintln!("Screenshot saved to {path:?}.");
std::process::exit(0);
}
}

let control_flow = if integration.should_close() {
EventResult::Exit
} else if repaint_after.is_zero() {
Expand Down Expand Up @@ -546,6 +569,8 @@ mod glow_integration {
std::thread::sleep(std::time::Duration::from_millis(10));
}

self.frame_nr += 1;

control_flow
} else {
EventResult::Wait
Expand Down Expand Up @@ -659,7 +684,7 @@ mod glow_integration {
if native_options.run_and_return {
with_event_loop(native_options, |event_loop, mut native_options| {
if native_options.centered {
centere_window_pos(event_loop.available_monitors().next(), &mut native_options);
center_window_pos(event_loop.available_monitors().next(), &mut native_options);
}

let glow_eframe =
Expand All @@ -670,7 +695,7 @@ mod glow_integration {
let event_loop = create_event_loop_builder(&mut native_options).build();

if native_options.centered {
centere_window_pos(event_loop.available_monitors().next(), &mut native_options);
center_window_pos(event_loop.available_monitors().next(), &mut native_options);
}

let glow_eframe = GlowWinitApp::new(&event_loop, app_name, native_options, app_creator);
Expand Down Expand Up @@ -718,6 +743,12 @@ mod wgpu_integration {
native_options: epi::NativeOptions,
app_creator: epi::AppCreator,
) -> Self {
#[cfg(feature = "__screenshot")]
assert!(
std::env::var("EFRAME_SCREENSHOT_TO").is_err(),
"EFRAME_SCREENSHOT_TO not yet implemented for wgpu backend"
);

Self {
repaint_proxy: Arc::new(std::sync::Mutex::new(event_loop.create_proxy())),
app_name: app_name.to_owned(),
Expand Down Expand Up @@ -1050,7 +1081,7 @@ mod wgpu_integration {
if native_options.run_and_return {
with_event_loop(native_options, |event_loop, mut native_options| {
if native_options.centered {
centere_window_pos(event_loop.available_monitors().next(), &mut native_options);
center_window_pos(event_loop.available_monitors().next(), &mut native_options);
}

let wgpu_eframe =
Expand All @@ -1061,7 +1092,7 @@ mod wgpu_integration {
let event_loop = create_event_loop_builder(&mut native_options).build();

if native_options.centered {
centere_window_pos(event_loop.available_monitors().next(), &mut native_options);
center_window_pos(event_loop.available_monitors().next(), &mut native_options);
}

let wgpu_eframe = WgpuWinitApp::new(&event_loop, app_name, native_options, app_creator);
Expand Down
32 changes: 32 additions & 0 deletions crates/egui_glow/src/painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,38 @@ impl Painter {
}
}

pub fn read_screen_rgba(&self, [w, h]: [u32; 2]) -> Vec<u8> {
let mut pixels = vec![0_u8; (w * h * 4) as usize];
unsafe {
self.gl.read_pixels(
0,
0,
w as _,
h as _,
glow::RGBA,
glow::UNSIGNED_BYTE,
glow::PixelPackData::Slice(&mut pixels),
);
}
pixels
}

pub fn read_screen_rgb(&self, [w, h]: [u32; 2]) -> Vec<u8> {
let mut pixels = vec![0_u8; (w * h * 3) as usize];
unsafe {
self.gl.read_pixels(
0,
0,
w as _,
h as _,
glow::RGB,
glow::UNSIGNED_BYTE,
glow::PixelPackData::Slice(&mut pixels),
);
}
pixels
}

unsafe fn destroy_gl(&self) {
self.gl.delete_program(self.program);
for tex in self.textures.values() {
Expand Down
4 changes: 3 additions & 1 deletion examples/confirm_exit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ publish = false


[dependencies]
eframe = { path = "../../crates/eframe" }
eframe = { path = "../../crates/eframe", features = [
"__screenshot", # __screenshot is so we can dump a ascreenshot using EFRAME_SCREENSHOT_TO
] }
4 changes: 4 additions & 0 deletions examples/confirm_exit/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Example how to show a confirm dialog before exiting an application.

```sh
cargo run -p confirm_exit
```

![](screenshot.png)
Binary file added examples/confirm_exit/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion examples/confirm_exit/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
use eframe::egui;

fn main() {
let options = eframe::NativeOptions::default();
let options = eframe::NativeOptions {
initial_window_size: Some(egui::vec2(320.0, 240.0)),
..Default::default()
};
eframe::run_native(
"Confirm exit",
options,
Expand Down
4 changes: 3 additions & 1 deletion examples/custom_3d_glow/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ publish = false


[dependencies]
eframe = { path = "../../crates/eframe", features = ["glow"] }
eframe = { path = "../../crates/eframe", features = [
"__screenshot", # __screenshot is so we can dump a ascreenshot using EFRAME_SCREENSHOT_TO
] }
egui_glow = { path = "../../crates/egui_glow" }
glow = "0.11"
2 changes: 2 additions & 0 deletions examples/custom_3d_glow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ If you are content of having egui sit on top of a 3D background, take a look at:
```sh
cargo run -p custom_3d_glow
```

![](screenshot.png)
Binary file added examples/custom_3d_glow/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion examples/custom_3d_three-d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ publish = false
crate-type = ["cdylib", "rlib"]

[dependencies]
eframe = { path = "../../crates/eframe", features = ["glow"] }
eframe = { path = "../../crates/eframe", features = [
"__screenshot", # __screenshot is so we can dump a ascreenshot using EFRAME_SCREENSHOT_TO
] }
egui_glow = { path = "../../crates/egui_glow" }
glow = "0.11"
three-d = { version = "0.13", default-features = false }
Expand Down
2 changes: 2 additions & 0 deletions examples/custom_3d_three-d/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ cargo run -p custom_3d_three-d
```
wasm-pack build examples/custom_3d_three-d --target web
```

![](screenshot.png)
Binary file added examples/custom_3d_three-d/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion examples/custom_font/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ publish = false


[dependencies]
eframe = { path = "../../crates/eframe" }
eframe = { path = "../../crates/eframe", features = [
"__screenshot", # __screenshot is so we can dump a ascreenshot using EFRAME_SCREENSHOT_TO
] }
4 changes: 4 additions & 0 deletions examples/custom_font/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Example of how to use custom fonts.

```sh
cargo run -p custom_font
```

![](screenshot.png)
Binary file added examples/custom_font/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion examples/custom_font/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
use eframe::egui;

fn main() {
let options = eframe::NativeOptions::default();
let options = eframe::NativeOptions {
initial_window_size: Some(egui::vec2(320.0, 240.0)),
..Default::default()
};
eframe::run_native(
"egui example: custom font",
options,
Expand Down
4 changes: 3 additions & 1 deletion examples/custom_font_style/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ publish = false


[dependencies]
eframe = { path = "../../crates/eframe" }
eframe = { path = "../../crates/eframe", features = [
"__screenshot", # __screenshot is so we can dump a ascreenshot using EFRAME_SCREENSHOT_TO
] }
5 changes: 4 additions & 1 deletion examples/custom_font_style/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
Example how to define custom test styles.

```sh
cargo run -p custom_font_style
```
![custom_font_style example](custom_font_style.png)

![](screenshot.png)
Binary file removed examples/custom_font_style/custom_font_style.png
Binary file not shown.
Binary file added examples/custom_font_style/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion examples/custom_window_frame/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ publish = false


[dependencies]
eframe = { path = "../../crates/eframe" }
eframe = { path = "../../crates/eframe", features = [
"__screenshot", # __screenshot is so we can dump a ascreenshot using EFRAME_SCREENSHOT_TO
] }
4 changes: 4 additions & 0 deletions examples/custom_window_frame/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Example how to show a custom window frame instead of the default OS window chrome decorations.

```sh
cargo run -p custom_window_frame
```

![](screenshot.png)
Binary file added examples/custom_window_frame/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/custom_window_frame/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ fn main() {
// To have rounded corners we need transparency:
transparent: true,
min_window_size: Some(egui::vec2(320.0, 100.0)),
initial_window_size: Some(egui::vec2(320.0, 240.0)),
..Default::default()
};
eframe::run_native(
Expand Down
4 changes: 3 additions & 1 deletion examples/download_image/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ publish = false


[dependencies]
eframe = { path = "../../crates/eframe" }
eframe = { path = "../../crates/eframe", features = [
"__screenshot", # __screenshot is so we can dump a ascreenshot using EFRAME_SCREENSHOT_TO
] }
egui_extras = { path = "../../crates/egui_extras", features = ["image"] }
ehttp = "0.2"
image = { version = "0.24", default-features = false, features = ["jpeg"] }
Expand Down
4 changes: 4 additions & 0 deletions examples/download_image/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Example how to download and show an image with eframe/egui.

```sh
cargo run -p download_image
```

![](screenshot.png)
Binary file added examples/download_image/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion examples/file_dialog/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ publish = false


[dependencies]
eframe = { path = "../../crates/eframe" }
eframe = { path = "../../crates/eframe", features = [
"__screenshot", # __screenshot is so we can dump a ascreenshot using EFRAME_SCREENSHOT_TO
] }
rfd = "0.10"
2 changes: 2 additions & 0 deletions examples/file_dialog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ How to show a file dialog using [`rfd`](https://github.com/PolyMeilex/rfd).
```sh
cargo run -p file_dialog
```

![](screenshot.png)
Binary file added examples/file_dialog/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/file_dialog/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use eframe::egui;
fn main() {
let options = eframe::NativeOptions {
drag_and_drop_support: true,
initial_window_size: Some(egui::vec2(320.0, 240.0)),
..Default::default()
};
eframe::run_native(
Expand Down
4 changes: 3 additions & 1 deletion examples/hello_world/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ publish = false


[dependencies]
eframe = { path = "../../crates/eframe" }
eframe = { path = "../../crates/eframe", features = [
"__screenshot", # __screenshot is so we can dump a ascreenshot using EFRAME_SCREENSHOT_TO
] }
tracing-subscriber = "0.3"
4 changes: 4 additions & 0 deletions examples/hello_world/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Example showing some UI controls like `Label`, `TextEdit`, `Slider`, `Button`.

```sh
cargo run -p hello_world
```

![](screenshot.png)
Binary file added examples/hello_world/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion examples/hello_world/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ fn main() {
// Log to stdout (if you run with `RUST_LOG=debug`).
tracing_subscriber::fmt::init();

let options = eframe::NativeOptions::default();
let options = eframe::NativeOptions {
initial_window_size: Some(egui::vec2(320.0, 240.0)),
..Default::default()
};
eframe::run_native(
"My egui App",
options,
Expand Down
Loading

0 comments on commit 48666e1

Please sign in to comment.