diff --git a/docs/TODO_ux.md b/docs/TODO_ux.md index cca902779c..b0edd1bc84 100644 --- a/docs/TODO_ux.md +++ b/docs/TODO_ux.md @@ -68,6 +68,8 @@ - speed - change ezgui API to allow uploading geometry once - the DrawMap stuff needs colorscheme and gfxctx then to setup easily... + - need display and colorscheme earlier + - short-term... mutable drawing? - what about color then? get fancy and plumb an override color uniform? - stop storing raw geometry when appropriate - should the API for batching be easier? make a bunch of mutable calls to GfxCtx-like thing, then flush it? diff --git a/editor/src/main.rs b/editor/src/main.rs index 1774e3aabf..8ceb8c3230 100644 --- a/editor/src/main.rs +++ b/editor/src/main.rs @@ -30,20 +30,25 @@ fn main() { .unwrap() .start("./profile") .unwrap();*/ + let mut canvas = ezgui::Canvas::new(1024, 768); + let cs = colors::ColorScheme::load().unwrap(); + if flags.sim_flags.load == "../data/raw_maps/ban_left_turn.abst" { ezgui::run( ui::UI::new( - tutorial::TutorialState::new(flags.sim_flags, &mut canvas), + tutorial::TutorialState::new(flags.sim_flags, &mut canvas, &cs), canvas, + cs, ), "A/B Street", ); } else { ezgui::run( ui::UI::new( - state::DefaultUIState::new(flags.sim_flags, flags.kml, &canvas, true), + state::DefaultUIState::new(flags.sim_flags, flags.kml, &canvas, &cs, true), canvas, + cs, ), "A/B Street", ); diff --git a/editor/src/plugins/edit/a_b_tests.rs b/editor/src/plugins/edit/a_b_tests.rs index 8e46b71400..0a9c1f7224 100644 --- a/editor/src/plugins/edit/a_b_tests.rs +++ b/editor/src/plugins/edit/a_b_tests.rs @@ -1,3 +1,4 @@ +use crate::colors::ColorScheme; use crate::objects::Ctx; use crate::plugins::{choose_edits, choose_scenario, load_ab_test, Plugin, PluginCtx}; use crate::state::{PerMapUI, PluginsPerMap}; @@ -44,7 +45,7 @@ impl Plugin for ABTestManager { ); if ctx.input.modal_action("run A/B test") { let ((new_primary, new_primary_plugins), new_secondary) = - launch_test(test, &ctx.primary.current_flags); + launch_test(test, &ctx.primary.current_flags, &ctx.cs); *ctx.primary = new_primary; *primary_plugins = new_primary_plugins; *ctx.secondary = Some(new_secondary); @@ -94,6 +95,7 @@ fn pick_ab_test(map: &Map, mut wizard: WrappedWizard) -> Option { fn launch_test( test: &ABTest, current_flags: &SimFlags, + cs: &ColorScheme, ) -> ((PerMapUI, PluginsPerMap), (PerMapUI, PluginsPerMap)) { info!("Launching A/B test {}...", test.test_name); let load = format!( @@ -115,6 +117,7 @@ fn launch_test( edits_name: test.edits1_name.clone(), }, None, + cs, true, ); let secondary = PerMapUI::new( @@ -125,6 +128,7 @@ fn launch_test( edits_name: test.edits2_name.clone(), }, None, + cs, true, ); // That's all! The scenario will be instantiated. diff --git a/editor/src/plugins/edit/map_edits.rs b/editor/src/plugins/edit/map_edits.rs index b68dbe5798..8dfaec962a 100644 --- a/editor/src/plugins/edit/map_edits.rs +++ b/editor/src/plugins/edit/map_edits.rs @@ -1,3 +1,4 @@ +use crate::colors::ColorScheme; use crate::objects::Ctx; use crate::plugins::{choose_edits, Plugin, PluginCtx}; use crate::state::{PerMapUI, PluginsPerMap}; @@ -30,6 +31,7 @@ impl Plugin for EditsManager { if manage_edits( &mut ctx.primary.current_flags, + &ctx.cs, &ctx.primary.map, &mut new_primary, self.wizard.wrap(ctx.input, ctx.canvas), @@ -53,6 +55,7 @@ impl Plugin for EditsManager { fn manage_edits( current_flags: &mut SimFlags, + cs: &ColorScheme, map: &Map, new_primary: &mut Option<(PerMapUI, PluginsPerMap)>, mut wizard: WrappedWizard, @@ -95,7 +98,7 @@ fn manage_edits( info!("Reloading everything..."); // TODO Properly retain enable_debug_plugins - *new_primary = Some(PerMapUI::new(flags, None, true)); + *new_primary = Some(PerMapUI::new(flags, None, cs, true)); Some(()) } _ => unreachable!(), diff --git a/editor/src/render/map.rs b/editor/src/render/map.rs index 648e985eb7..6a3c6f34a4 100644 --- a/editor/src/render/map.rs +++ b/editor/src/render/map.rs @@ -1,3 +1,4 @@ +use crate::colors::ColorScheme; use crate::objects::ID; use crate::render::area::DrawArea; use crate::render::building::DrawBuilding; @@ -42,7 +43,12 @@ pub struct DrawMap { } impl DrawMap { - pub fn new(map: &Map, raw_extra_shapes: Vec, timer: &mut Timer) -> DrawMap { + pub fn new( + map: &Map, + raw_extra_shapes: Vec, + cs: &ColorScheme, + timer: &mut Timer, + ) -> DrawMap { let mut lanes: Vec = Vec::new(); timer.start_iter("make DrawLanes", map.all_lanes().len()); for l in map.all_lanes() { diff --git a/editor/src/state.rs b/editor/src/state.rs index 3e899b557e..1d803a59f0 100644 --- a/editor/src/state.rs +++ b/editor/src/state.rs @@ -54,12 +54,13 @@ impl DefaultUIState { flags: SimFlags, kml: Option, canvas: &Canvas, + cs: &ColorScheme, enable_debug_controls: bool, ) -> DefaultUIState { // Do this first to trigger the log console initialization, so anything logged by sim::load // isn't lost. view::logs::DisplayLogs::initialize(); - let (primary, primary_plugins) = PerMapUI::new(flags, kml, enable_debug_controls); + let (primary, primary_plugins) = PerMapUI::new(flags, kml, cs, enable_debug_controls); let mut state = DefaultUIState { primary, primary_plugins, @@ -425,6 +426,7 @@ impl PerMapUI { pub fn new( flags: SimFlags, kml: Option, + cs: &ColorScheme, enable_debug_controls: bool, ) -> (PerMapUI, PluginsPerMap) { let mut timer = abstutil::Timer::new("setup PerMapUI"); @@ -445,7 +447,7 @@ impl PerMapUI { }; timer.start("draw_map"); - let draw_map = DrawMap::new(&map, extra_shapes, &mut timer); + let draw_map = DrawMap::new(&map, extra_shapes, cs, &mut timer); timer.stop("draw_map"); let state = PerMapUI { diff --git a/editor/src/tutorial.rs b/editor/src/tutorial.rs index 3569c45e68..6fc002d662 100644 --- a/editor/src/tutorial.rs +++ b/editor/src/tutorial.rs @@ -23,9 +23,9 @@ enum State { const SPAWN_CARS_PER_BORDER: usize = 100 * 10; impl TutorialState { - pub fn new(flags: SimFlags, canvas: &mut Canvas) -> TutorialState { + pub fn new(flags: SimFlags, canvas: &mut Canvas, cs: &ColorScheme) -> TutorialState { TutorialState { - main: DefaultUIState::new(flags, None, canvas, false), + main: DefaultUIState::new(flags, None, canvas, cs, false), state: State::GiveInstructions(LogScroller::new_from_lines(vec![ "Welcome to the A/B Street tutorial!".to_string(), "".to_string(), diff --git a/editor/src/ui.rs b/editor/src/ui.rs index 31251e546e..2b31bb69ea 100644 --- a/editor/src/ui.rs +++ b/editor/src/ui.rs @@ -18,6 +18,7 @@ use std::process; pub struct UI { state: S, canvas: Canvas, + // TODO Not sure why this needs to live here and not in state cs: ColorScheme, } @@ -321,12 +322,8 @@ impl GUI for UI { } impl UI { - pub fn new(state: S, canvas: Canvas) -> UI { - let mut ui = UI { - state, - canvas, - cs: ColorScheme::load().unwrap(), - }; + pub fn new(state: S, canvas: Canvas, cs: ColorScheme) -> UI { + let mut ui = UI { state, canvas, cs }; match abstutil::read_json::("../editor_state") { Ok(ref state) if ui.state.get_state().primary.map.get_name() == &state.map_name => { diff --git a/ezgui/src/drawing.rs b/ezgui/src/drawing.rs index ab22a10e58..629bc97b12 100644 --- a/ezgui/src/drawing.rs +++ b/ezgui/src/drawing.rs @@ -163,11 +163,40 @@ impl<'a> GfxCtx<'a> { } pub fn draw_polygon_batch(&mut self, list: Vec<(Color, &Polygon)>) { - let obj = self.prerender(list); + let obj = Prerender { + display: self.display, + } + .upload(list); + self.num_new_uploads += 1; self.draw(&obj); } - pub fn prerender(&mut self, list: Vec<(Color, &Polygon)>) -> Drawable { + pub fn draw(&mut self, obj: &Drawable) { + self.target + .draw( + &obj.vertex_buffer, + &obj.index_buffer, + &self.program, + &self.uniforms, + &self.params, + ) + .unwrap(); + self.num_draw_calls += 1; + } +} + +pub struct Prerender<'a> { + display: &'a glium::Display, +} + +// Something that's been sent to the GPU already. +pub struct Drawable { + vertex_buffer: glium::VertexBuffer, + index_buffer: glium::IndexBuffer, +} + +impl<'a> Prerender<'a> { + pub fn upload(&self, list: Vec<(Color, &Polygon)>) -> Drawable { let mut vertices: Vec = Vec::new(); let mut indices: Vec = Vec::new(); @@ -192,28 +221,10 @@ impl<'a> GfxCtx<'a> { &indices, ) .unwrap(); - self.num_new_uploads += 1; Drawable { - vertex_buffer, index_buffer, } - } - - pub fn draw(&mut self, obj: &Drawable) { - self.target - .draw( - &obj.vertex_buffer, - &obj.index_buffer, - &self.program, - &self.uniforms, - &self.params, - ) - .unwrap(); - self.num_draw_calls += 1; + vertex_buffer, + index_buffer, + } } } - -// Something that's been sent to the GPU already. -pub struct Drawable { - vertex_buffer: glium::VertexBuffer, - index_buffer: glium::IndexBuffer, -} diff --git a/ezgui/src/lib.rs b/ezgui/src/lib.rs index c72a51d89d..720fc75b28 100644 --- a/ezgui/src/lib.rs +++ b/ezgui/src/lib.rs @@ -15,7 +15,7 @@ mod wizard; pub use crate::canvas::{Canvas, HorizontalAlignment, VerticalAlignment, BOTTOM_LEFT, CENTERED}; pub use crate::color::Color; -pub use crate::drawing::{Drawable, GfxCtx}; +pub use crate::drawing::{Drawable, GfxCtx, Prerender}; pub use crate::event::{Event, Key}; pub use crate::input::{ModalMenu, UserInput}; pub use crate::log_scroller::LogScroller;