try screenshot capture again. it's very slow and broken.

This commit is contained in:
Dustin Carlino 2019-01-13 14:47:11 -08:00
parent 66006618df
commit a94fddb209
5 changed files with 132 additions and 43 deletions

View File

@ -22,6 +22,8 @@ pub struct UI<S: UIState> {
state: S,
canvas: Canvas,
cs: ColorScheme,
// TODO Shouldn't this be a proper plugin?
take_screenshot: bool,
}
impl<S: UIState> GUI<RenderingHints> for UI<S> {
@ -232,6 +234,11 @@ impl<S: UIState> GUI<RenderingHints> for UI<S> {
input.populate_osd(&mut hints.osd);
self.take_screenshot = false;
if input.unimportant_key_pressed(Key::F1, "take screenshot") {
self.take_screenshot = true;
}
(hints.mode, hints)
}
@ -240,6 +247,10 @@ impl<S: UIState> GUI<RenderingHints> for UI<S> {
}
fn draw(&self, g: &mut GfxCtx, hints: &RenderingHints) {
if self.take_screenshot {
g.render_to_buffer(&self.canvas);
}
g.clear(self.cs.get_def("map background", Color::rgb(242, 239, 233)));
let ctx = Ctx {
@ -270,6 +281,11 @@ impl<S: UIState> GUI<RenderingHints> for UI<S> {
// soon, so meh
self.canvas
.draw_blocking_text(g, hints.osd.clone(), BOTTOM_LEFT);
if self.take_screenshot {
g.save_buffer("screenshot.png");
info!("Captured screenshot.png");
}
}
fn dump_before_abort(&self) {
@ -298,6 +314,7 @@ impl<S: UIState> UI<S> {
state,
canvas,
cs: ColorScheme::load().unwrap(),
take_screenshot: false,
};
match abstutil::read_json::<EditorState>("../editor_state") {

View File

@ -8,17 +8,14 @@ edition = "2018"
abstutil = { path = "../abstutil" }
dimensioned = { git = "https://github.com/paholg/dimensioned", rev = "0e1076ebfa5128d1ee544bdc9754c948987b6fe3", features = ["serde"] }
geom = { path = "../geom" }
graphics_buffer = "0.5.0"
log = "0.4.5"
ordered-float = "1.0.1"
palette = "0.4"
piston = "0.37.0"
piston2d-graphics = "0.26.0"
piston2d-opengl_graphics = "0.53.0"
# Newer versions start reading DPI, which is very broken on my system.
# WINIT_HIDPI_FACTOR=1.0 as an environment variable fixes, but just pin to an
# older version for now... before
# https://github.com/tomaka/winit/commit/1b74822cfc0cb7fba4ed4940a3faae9499fcda95.
pistoncore-glutin_window = "0.47.0"
piston = "0.39.0"
piston2d-graphics = "0.28.0"
piston2d-opengl_graphics = "0.57.0"
pistoncore-glutin_window = "0.51.1"
serde = "1.0"
serde_derive = "1.0"
textwrap = "0.11"

View File

@ -152,6 +152,7 @@ pub enum Key {
RightArrow,
UpArrow,
DownArrow,
F1,
}
impl Key {
@ -210,7 +211,8 @@ impl Key {
| Key::LeftArrow
| Key::RightArrow
| Key::UpArrow
| Key::DownArrow => None,
| Key::DownArrow
| Key::F1 => None,
}
}
@ -227,6 +229,7 @@ impl Key {
Key::RightArrow => "→ arrow".to_string(),
Key::UpArrow => "".to_string(),
Key::DownArrow => "".to_string(),
Key::F1 => "F1".to_string(),
// These have to_char, but override here
Key::Space => "Space".to_string(),
_ => self.to_char(false).unwrap().to_string(),
@ -294,6 +297,7 @@ impl Key {
pi::Key::Right => Key::RightArrow,
pi::Key::Up => Key::UpArrow,
pi::Key::Down => Key::DownArrow,
pi::Key::F1 => Key::F1,
_ => {
println!("Unknown piston key {:?}", key);
return None;

View File

@ -28,6 +28,7 @@ pub use crate::top_menu::{Folder, TopMenu};
pub use crate::wizard::{Wizard, WrappedWizard};
use geom::Pt2D;
use graphics::Transformed;
use graphics_buffer::{RenderBuffer, IDENTITY};
use opengl_graphics::GlGraphics;
use std::mem;
@ -38,7 +39,10 @@ pub const TOP_MENU_HEIGHT: f64 = text::LINE_HEIGHT;
pub struct GfxCtx<'a> {
orig_ctx: graphics::Context,
ctx: graphics::Context,
// TODO Either gfx or save_to_buffer, not both.
gfx: &'a mut GlGraphics,
// TODO The code duplication below sucks. Make the generics work.
save_to_buffer: Option<RenderBuffer>,
}
impl<'a> GfxCtx<'a> {
@ -47,9 +51,25 @@ impl<'a> GfxCtx<'a> {
gfx: g,
orig_ctx: c,
ctx: c,
save_to_buffer: None,
}
}
pub fn render_to_buffer(&mut self, canvas: &Canvas) {
assert!(self.save_to_buffer.is_none());
self.save_to_buffer = Some(RenderBuffer::new(
canvas.window_height as u32,
canvas.window_height as u32,
));
self.orig_ctx.view = IDENTITY;
self.orig_ctx.transform = IDENTITY;
canvas.start_drawing(self);
}
pub fn save_buffer(&mut self, filename: &str) {
self.save_to_buffer.take().unwrap().save(filename).unwrap();
}
// Up to the caller to call unfork()!
// TODO Canvas doesn't understand this change, so things like text drawing that use
// map_to_screen will just be confusing.
@ -71,7 +91,11 @@ impl<'a> GfxCtx<'a> {
}
pub fn clear(&mut self, color: Color) {
graphics::clear(color.0, self.gfx);
if let Some(ref mut buf) = self.save_to_buffer {
graphics::clear(color.0, buf);
} else {
graphics::clear(color.0, self.gfx);
}
}
// Use graphics::Line internally for now, but make it easy to switch to something else by
@ -88,18 +112,33 @@ impl<'a> GfxCtx<'a> {
pub fn draw_arrow(&mut self, color: Color, thickness: f64, line: &geom::Line) {
// TODO Raw method doesn't work yet in all cases...
graphics::Line::new_round(color.0, thickness).draw_arrow(
[
line.pt1().x(),
line.pt1().y(),
line.pt2().x(),
line.pt2().y(),
],
2.0 * thickness,
&self.ctx.draw_state,
self.ctx.transform,
self.gfx,
);
if let Some(ref mut buf) = self.save_to_buffer {
graphics::Line::new_round(color.0, thickness).draw_arrow(
[
line.pt1().x(),
line.pt1().y(),
line.pt2().x(),
line.pt2().y(),
],
2.0 * thickness,
&self.ctx.draw_state,
self.ctx.transform,
buf,
);
} else {
graphics::Line::new_round(color.0, thickness).draw_arrow(
[
line.pt1().x(),
line.pt1().y(),
line.pt2().x(),
line.pt2().y(),
],
2.0 * thickness,
&self.ctx.draw_state,
self.ctx.transform,
self.gfx,
);
}
/*use dimensioned::si;
let head_size = 2.0 * thickness;
@ -135,12 +174,55 @@ impl<'a> GfxCtx<'a> {
}
pub fn draw_polygon(&mut self, color: Color, poly: &geom::Polygon) {
for tri in &poly.triangles {
graphics::Polygon::new(color.0).draw(
&[
[tri.pt1.x(), tri.pt1.y()],
[tri.pt2.x(), tri.pt2.y()],
[tri.pt3.x(), tri.pt3.y()],
if let Some(ref mut buf) = self.save_to_buffer {
for tri in &poly.triangles {
graphics::Polygon::new(color.0).draw(
&[
[tri.pt1.x(), tri.pt1.y()],
[tri.pt2.x(), tri.pt2.y()],
[tri.pt3.x(), tri.pt3.y()],
],
&self.ctx.draw_state,
self.ctx.transform,
buf,
);
}
} else {
for tri in &poly.triangles {
graphics::Polygon::new(color.0).draw(
&[
[tri.pt1.x(), tri.pt1.y()],
[tri.pt2.x(), tri.pt2.y()],
[tri.pt3.x(), tri.pt3.y()],
],
&self.ctx.draw_state,
self.ctx.transform,
self.gfx,
);
}
}
}
pub fn draw_circle(&mut self, color: Color, circle: &geom::Circle) {
if let Some(ref mut buf) = self.save_to_buffer {
graphics::Ellipse::new(color.0).draw(
[
circle.center.x() - circle.radius,
circle.center.y() - circle.radius,
2.0 * circle.radius,
2.0 * circle.radius,
],
&self.ctx.draw_state,
self.ctx.transform,
buf,
);
} else {
graphics::Ellipse::new(color.0).draw(
[
circle.center.x() - circle.radius,
circle.center.y() - circle.radius,
2.0 * circle.radius,
2.0 * circle.radius,
],
&self.ctx.draw_state,
self.ctx.transform,
@ -148,20 +230,6 @@ impl<'a> GfxCtx<'a> {
);
}
}
pub fn draw_circle(&mut self, color: Color, circle: &geom::Circle) {
graphics::Ellipse::new(color.0).draw(
[
circle.center.x() - circle.radius,
circle.center.y() - circle.radius,
2.0 * circle.radius,
2.0 * circle.radius,
],
&self.ctx.draw_state,
self.ctx.transform,
self.gfx,
);
}
}
pub struct ToggleableLayer {

View File

@ -4,7 +4,7 @@ use glutin_window::GlutinWindow;
use opengl_graphics::{GlGraphics, OpenGL};
use piston::event_loop::{EventLoop, EventSettings, Events};
use piston::window::WindowSettings;
use std::{panic, process};
use std::{env, panic, process};
pub trait GUI<T> {
// Called once
@ -30,6 +30,9 @@ pub enum EventLoopMode {
}
pub fn run<T, G: GUI<T>>(mut gui: G, window_title: &str) {
// DPI is broken on my system; force the old behavior.
env::set_var("WINIT_HIDPI_FACTOR", "1.0");
let opengl = OpenGL::V3_2;
let settings = WindowSettings::new(
window_title,