at last, prerender cars

This commit is contained in:
Dustin Carlino 2019-02-02 14:28:00 -08:00
parent f9ccecad26
commit 3f4711b13d
4 changed files with 41 additions and 33 deletions

View File

@ -1,10 +1,5 @@
# TODO - GUI and UX # TODO - GUI and UX
## Performance
- cache draw agents
- actually use Drawables in the places
## Quick n easy ## Quick n easy
- try showing traffic signals by little boxes at the end of lanes - try showing traffic signals by little boxes at the end of lanes
@ -71,8 +66,6 @@
- speed - speed
- show FPS or some kind of measure of lag - show FPS or some kind of measure of lag
- drawing cars is expensive
- at least cache them until tick changes
- sleep better in the event loop - sleep better in the event loop
- first make UserInput borrow state and not need to consume - first make UserInput borrow state and not need to consume
- optimize zoomed-out experience... one polygon per road - optimize zoomed-out experience... one polygon per road
@ -95,3 +88,8 @@
- experiment with batching and not passing colors - experiment with batching and not passing colors
- specialized shaders for common shapes like circles? - specialized shaders for common shapes like circles?
- try https://docs.rs/dymod/0.1.0/dymod/ to link in a release-mode ezgui crate? - try https://docs.rs/dymod/0.1.0/dymod/ to link in a release-mode ezgui crate?
## Performance
- crosswalks still not batched
- it's a pity we have to redo DrawCar work for all those parked cars every tick

View File

@ -1,6 +1,7 @@
use crate::colors::ColorScheme;
use crate::objects::{Ctx, ID}; use crate::objects::{Ctx, ID};
use crate::render::{RenderOptions, Renderable}; use crate::render::{RenderOptions, Renderable};
use ezgui::{Color, GfxCtx}; use ezgui::{Color, Drawable, GfxCtx, Prerender};
use geom::{Angle, Bounds, Circle, Distance, PolyLine, Polygon, Pt2D}; use geom::{Angle, Bounds, Circle, Distance, PolyLine, Polygon, Pt2D};
use map_model::{Map, TurnType}; use map_model::{Map, TurnType};
use sim::{CarID, CarState, DrawCarInput}; use sim::{CarID, CarState, DrawCarInput};
@ -19,12 +20,13 @@ pub struct DrawCar {
right_blinker_on: bool, right_blinker_on: bool,
// TODO maybe also draw lookahead buffer to know what the car is considering // TODO maybe also draw lookahead buffer to know what the car is considering
stopping_buffer: Option<Polygon>, stopping_buffer: Option<Polygon>,
state: CarState,
zorder: isize, zorder: isize,
draw_default: Drawable,
} }
impl DrawCar { impl DrawCar {
pub fn new(input: DrawCarInput, map: &Map) -> DrawCar { pub fn new(input: DrawCarInput, map: &Map, prerender: &Prerender, cs: &ColorScheme) -> DrawCar {
let (left_blinker_on, right_blinker_on) = if let Some(t) = input.waiting_for_turn { let (left_blinker_on, right_blinker_on) = if let Some(t) = input.waiting_for_turn {
match map.get_t(t).turn_type { match map.get_t(t).turn_type {
TurnType::Left => (true, false), TurnType::Left => (true, false),
@ -73,9 +75,32 @@ impl DrawCar {
) )
}; };
let body_polygon = input.body.make_polygons(CAR_WIDTH);
let draw_default = prerender.upload_borrowed(vec![
(
// TODO if it's a bus, color it differently -- but how? :\
match input.state {
CarState::Debug => cs
.get_def("debug car", Color::BLUE.alpha(0.8))
.shift(input.id.0),
CarState::Moving => cs.get_def("moving car", Color::CYAN).shift(input.id.0),
CarState::Stuck => cs
.get_def("stuck car", Color::rgb_f(0.9, 0.0, 0.0))
.shift(input.id.0),
CarState::Parked => cs
.get_def("parked car", Color::rgb(180, 233, 76))
.shift(input.id.0),
},
&body_polygon,
),
(cs.get_def("car window", Color::BLACK), &front_window),
(cs.get("car window"), &back_window),
]);
DrawCar { DrawCar {
id: input.id, id: input.id,
body_polygon: input.body.make_polygons(CAR_WIDTH), body_polygon,
window_polygons: vec![front_window, back_window], window_polygons: vec![front_window, back_window],
left_blinkers: Some(( left_blinkers: Some((
Circle::new( Circle::new(
@ -112,8 +137,8 @@ impl DrawCar {
left_blinker_on, left_blinker_on,
right_blinker_on, right_blinker_on,
stopping_buffer, stopping_buffer,
state: input.state,
zorder: input.on.get_zorder(map), zorder: input.on.get_zorder(map),
draw_default,
} }
} }
} }
@ -124,30 +149,14 @@ impl Renderable for DrawCar {
} }
fn draw(&self, g: &mut GfxCtx, opts: RenderOptions, ctx: &Ctx) { fn draw(&self, g: &mut GfxCtx, opts: RenderOptions, ctx: &Ctx) {
let color = opts.color.unwrap_or_else(|| { if let Some(color) = opts.color {
// TODO if it's a bus, color it differently -- but how? :\
match self.state {
CarState::Debug => ctx
.cs
.get_def("debug car", Color::BLUE.alpha(0.8))
.shift(self.id.0),
CarState::Moving => ctx.cs.get_def("moving car", Color::CYAN).shift(self.id.0),
CarState::Stuck => ctx
.cs
.get_def("stuck car", Color::rgb_f(0.9, 0.0, 0.0))
.shift(self.id.0),
CarState::Parked => ctx
.cs
.get_def("parked car", Color::rgb(180, 233, 76))
.shift(self.id.0),
}
});
{
let mut draw = vec![(color, &self.body_polygon)]; let mut draw = vec![(color, &self.body_polygon)];
for p in &self.window_polygons { for p in &self.window_polygons {
draw.push((ctx.cs.get_def("car window", Color::BLACK), p)); draw.push((ctx.cs.get("car window"), p));
} }
g.draw_polygon_batch(draw); g.draw_polygon_batch(draw);
} else {
g.redraw(&self.draw_default);
} }
let blinker_on = ctx.cs.get_def("blinker on", Color::RED); let blinker_on = ctx.cs.get_def("blinker on", Color::RED);

View File

@ -275,6 +275,7 @@ impl DrawMap {
} }
} }
// TODO Invalidate when we interactively spawn stuff elsewhere?
pub struct AgentCache { pub struct AgentCache {
tick: Option<Tick>, tick: Option<Tick>,
agents_per_on: HashMap<Traversable, Vec<Box<Renderable>>>, agents_per_on: HashMap<Traversable, Vec<Box<Renderable>>>,

View File

@ -71,6 +71,6 @@ pub fn draw_vehicle(
if input.vehicle_type == VehicleType::Bike { if input.vehicle_type == VehicleType::Bike {
Box::new(DrawBike::new(input, prerender, cs)) Box::new(DrawBike::new(input, prerender, cs))
} else { } else {
Box::new(DrawCar::new(input, map)) Box::new(DrawCar::new(input, map, prerender, cs))
} }
} }