FancyColor -> Fill (#334)

This commit is contained in:
Michael Kirk 2020-09-17 23:34:25 -07:00 committed by GitHub
parent 16ed4ca457
commit cb84b729f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 52 additions and 59 deletions

View File

@ -3,9 +3,7 @@ use abstutil::Counter;
use geom::{Circle, Distance, Line, Polygon, Pt2D};
use map_model::{BuildingID, BusStopID, IntersectionID, LaneID, Map, ParkingLotID, RoadID};
use std::collections::HashMap;
use widgetry::{
Color, Drawable, EventCtx, FancyColor, GeomBatch, Line, LinearGradient, Text, Widget,
};
use widgetry::{Color, Drawable, EventCtx, Fill, GeomBatch, Line, LinearGradient, Text, Widget};
pub struct ColorDiscrete<'a> {
map: &'a Map,
@ -120,8 +118,8 @@ impl ColorLegend {
let n = scale.0.len();
let mut batch = GeomBatch::new();
let width_each = width / ((n - 1) as f64);
batch.fancy_push(
FancyColor::LinearGradient(LinearGradient {
batch.push(
Fill::LinearGradient(LinearGradient {
line: Line::must_new(Pt2D::new(0.0, 0.0), Pt2D::new(width, 0.0)),
stops: scale
.0

View File

@ -10,7 +10,7 @@ use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::collections::HashSet;
use widgetry::{
hotkey, lctrl, Btn, Checkbox, Color, Drawable, EventCtx, FancyColor, GeomBatch, GfxCtx,
hotkey, lctrl, Btn, Checkbox, Color, Drawable, EventCtx, Fill, GeomBatch, GfxCtx,
HorizontalAlignment, Key, Line, LinePlot, Outcome, Panel, PlotOptions, Series, Text, TextExt,
Texture, UpdateType, VerticalAlignment, Widget, GUI,
};
@ -216,7 +216,7 @@ fn setup_texture_demo(ctx: &mut EventCtx) -> Drawable {
rect = rect.translate(200.0, 900.0);
// Texture::NOOP should always be pure white, since all "non-textured" colors are multiplied by
// Texture::NOOP (Texture::NOOP.0 == 0)
batch.fancy_push(FancyColor::Texture(Texture::NOOP), rect);
batch.push(Texture::NOOP, rect);
let triangle = geom::Triangle {
pt1: Pt2D::new(0.0, 100.0),
@ -225,19 +225,16 @@ fn setup_texture_demo(ctx: &mut EventCtx) -> Drawable {
};
let mut triangle_poly = Polygon::from_triangle(&triangle);
triangle_poly = triangle_poly.translate(400.0, 900.0);
batch.fancy_push(FancyColor::Texture(Texture::SAND), triangle_poly);
batch.push(Texture::SAND, triangle_poly);
let circle = geom::Circle::new(Pt2D::new(50.0, 50.0), geom::Distance::meters(50.0));
let mut circle_poly = circle.to_polygon();
circle_poly = circle_poly.translate(600.0, 900.0);
batch.fancy_push(
FancyColor::ColoredTexture(Color::RED, Texture::SAND),
circle_poly.clone(),
);
batch.fancy_push(
FancyColor::Texture(Texture::SNOW_PERSON),
batch.push(
Fill::ColoredTexture(Color::RED, Texture::SAND),
circle_poly.clone(),
);
batch.push(Texture::SNOW_PERSON, circle_poly.clone());
batch.upload(ctx)
}

View File

@ -92,7 +92,7 @@ impl WindowAdapter {
}
}
/// Uploads a sprite sheet of textures to the GPU so they can be used by FancyColor::Texture and
/// Uploads a sprite sheet of textures to the GPU so they can be used by Fill::Texture and
/// friends to paint shapes.
///
/// `path` - image file which is a grid of images.
@ -169,7 +169,7 @@ fn load_textures(
);
// In order to avoid branching in our shader logic, all shapes are rendered with a texture.
// Even "non-textured" styles like FancyColor::RGBA, use a "default" no-op (pure white) texture,
// Even "non-textured" styles like Fill::Color, use a "default" no-op (pure white) texture,
// which we generate here.
let mut formatted_pixels: Vec<image::Rgba<u8>> =
vec![image::Rgba([255; 4]); (sprite_length * sprite_length) as usize];

View File

@ -20,10 +20,9 @@ impl fmt::Display for Color {
}
}
// TODO Maybe needs a better name
#[derive(Debug, Clone, PartialEq)]
pub enum FancyColor {
RGBA(Color),
pub enum Fill {
Color(Color),
LinearGradient(LinearGradient),
/// Once uploaded, textures are addressed by their id, starting from 1, from left to right, top
@ -45,7 +44,7 @@ pub enum FancyColor {
ColoredTexture(Color, Texture),
}
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Texture(u32);
#[allow(dead_code)]
@ -149,7 +148,7 @@ pub struct LinearGradient {
}
impl LinearGradient {
pub(crate) fn new(lg: &usvg::LinearGradient) -> FancyColor {
pub(crate) fn new(lg: &usvg::LinearGradient) -> Fill {
let line = Line::must_new(Pt2D::new(lg.x1, lg.y1), Pt2D::new(lg.x2, lg.y2));
let mut stops = Vec::new();
for stop in &lg.stops {
@ -161,7 +160,7 @@ impl LinearGradient {
);
stops.push((stop.offset.value(), color));
}
FancyColor::LinearGradient(LinearGradient { line, stops })
Fill::LinearGradient(LinearGradient { line, stops })
}
fn interp(&self, pt: Pt2D) -> Color {
@ -196,18 +195,30 @@ fn lerp(pct: f64, (x1, x2): (f32, f32)) -> f32 {
x1 + (pct as f32) * (x2 - x1)
}
impl FancyColor {
impl Fill {
pub(crate) fn shader_style(&self, pt: Pt2D) -> [f32; 5] {
match self {
FancyColor::RGBA(c) => [c.r, c.g, c.b, c.a, 0.0],
FancyColor::LinearGradient(ref lg) => {
Fill::Color(c) => [c.r, c.g, c.b, c.a, 0.0],
Fill::LinearGradient(ref lg) => {
let c = lg.interp(pt);
[c.r, c.g, c.b, c.a, 0.0]
}
FancyColor::Texture(texture) => [1.0, 1.0, 1.0, 1.0, texture.0 as f32],
FancyColor::ColoredTexture(color, texture) => {
Fill::Texture(texture) => [1.0, 1.0, 1.0, 1.0, texture.0 as f32],
Fill::ColoredTexture(color, texture) => {
[color.r, color.g, color.b, color.a, texture.0 as f32]
}
}
}
}
impl std::convert::From<Color> for Fill {
fn from(color: Color) -> Fill {
Fill::Color(color)
}
}
impl std::convert::From<Texture> for Fill {
fn from(texture: Texture) -> Fill {
Fill::Texture(texture)
}
}

View File

@ -1,14 +1,13 @@
use crate::widgets::button::BtnBuilder;
use crate::{
svg, Btn, Color, DeferDraw, Drawable, EventCtx, FancyColor, GfxCtx, Prerender, ScreenDims,
Widget,
svg, Btn, Color, DeferDraw, Drawable, EventCtx, Fill, GfxCtx, Prerender, ScreenDims, Widget,
};
use geom::{Angle, Bounds, Polygon, Pt2D};
/// A mutable builder for a group of colored polygons.
#[derive(Clone)]
pub struct GeomBatch {
pub(crate) list: Vec<(FancyColor, Polygon)>,
pub(crate) list: Vec<(Fill, Polygon)>,
pub autocrop_dims: bool,
}
@ -24,33 +23,21 @@ impl GeomBatch {
/// Creates a batch of colored polygons.
pub fn from(list: Vec<(Color, Polygon)>) -> GeomBatch {
GeomBatch {
list: list
.into_iter()
.map(|(c, p)| (FancyColor::RGBA(c), p))
.collect(),
list: list.into_iter().map(|(c, p)| (Fill::Color(c), p)).collect(),
autocrop_dims: true,
}
}
/// Adds a single colored polygon.
pub fn push(&mut self, color: Color, p: Polygon) {
self.list.push((FancyColor::RGBA(color), p));
}
// TODO Not sure about this
pub fn fancy_push(&mut self, color: FancyColor, p: Polygon) {
self.list.push((color, p));
// Adds a single polygon, painted according to `Fill`
pub fn push<F: Into<Fill>>(&mut self, fill: F, p: Polygon) {
self.list.push((fill.into(), p));
}
/// Applies one color to many polygons.
pub fn extend(&mut self, color: Color, polys: Vec<Polygon>) {
/// Applies one Fill to many polygons.
pub fn extend<F: Into<Fill>>(&mut self, fill: F, polys: Vec<Polygon>) {
let fill = fill.into();
for p in polys {
self.list.push((FancyColor::RGBA(color), p));
}
}
pub fn fancy_extend(&mut self, color: FancyColor, polys: Vec<Polygon>) {
for p in polys {
self.list.push((color.clone(), p));
self.list.push((fill.clone(), p));
}
}
@ -60,7 +47,7 @@ impl GeomBatch {
}
/// Returns the colored polygons in this batch, destroying the batch.
pub fn consume(self) -> Vec<(FancyColor, Polygon)> {
pub fn consume(self) -> Vec<(Fill, Polygon)> {
self.list
}
@ -155,7 +142,7 @@ impl GeomBatch {
/// Transforms all colors in a batch.
pub fn color(mut self, transformation: RewriteColor) -> GeomBatch {
for (fancy, _) in &mut self.list {
if let FancyColor::RGBA(ref mut c) = fancy {
if let Fill::Color(ref mut c) = fancy {
*c = transformation.apply(*c);
}
}

View File

@ -56,7 +56,7 @@ mod backend {
pub use crate::backend::Drawable;
pub use crate::canvas::{Canvas, HorizontalAlignment, VerticalAlignment};
pub use crate::color::{Color, FancyColor, LinearGradient, Texture};
pub use crate::color::{Color, Fill, LinearGradient, Texture};
pub use crate::drawing::{GfxCtx, Prerender};
pub use crate::event::{hotkey, hotkeys, lctrl, Event, Key, MultiKey};
pub use crate::event_ctx::{EventCtx, UpdateType};

View File

@ -1,4 +1,4 @@
use crate::{Color, FancyColor, GeomBatch, LinearGradient, Prerender};
use crate::{Color, Fill, GeomBatch, LinearGradient, Prerender};
use abstutil::VecMap;
use geom::{Bounds, Polygon, Pt2D};
use lyon::math::Point;
@ -47,7 +47,7 @@ pub fn add_svg_inner(
let mut fill_tess = tessellation::FillTessellator::new();
let mut stroke_tess = tessellation::StrokeTessellator::new();
// TODO This breaks on start.svg; the order there matters. color1, color2, then color1 again.
let mut mesh_per_color: VecMap<FancyColor, VertexBuffers<_, u16>> = VecMap::new();
let mut mesh_per_color: VecMap<Fill, VertexBuffers<_, u16>> = VecMap::new();
for node in svg_tree.root().descendants() {
if let usvg::NodeKind::Path(ref p) = *node.borrow() {
@ -79,7 +79,7 @@ pub fn add_svg_inner(
}
for (color, mesh) in mesh_per_color.consume() {
batch.fancy_push(
batch.push(
color,
Polygon::precomputed(
mesh.vertices
@ -204,7 +204,7 @@ fn convert_stroke(
s: &usvg::Stroke,
tolerance: f32,
tree: &usvg::Tree,
) -> (FancyColor, tessellation::StrokeOptions) {
) -> (Fill, tessellation::StrokeOptions) {
let color = convert_color(&s.paint, s.opacity.value(), tree);
let linecap = match s.linecap {
usvg::LineCap::Butt => tessellation::LineCap::Butt,
@ -225,9 +225,9 @@ fn convert_stroke(
(color, opt)
}
fn convert_color(paint: &usvg::Paint, opacity: f64, tree: &usvg::Tree) -> FancyColor {
fn convert_color(paint: &usvg::Paint, opacity: f64, tree: &usvg::Tree) -> Fill {
match paint {
usvg::Paint::Color(c) => FancyColor::RGBA(Color::rgba(
usvg::Paint::Color(c) => Fill::Color(Color::rgba(
c.red as usize,
c.green as usize,
c.blue as usize,