mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-22 13:51:33 +03:00
127 lines
4.3 KiB
Rust
127 lines
4.3 KiB
Rust
use crate::ScreenDims;
|
|
use geom::Angle;
|
|
use serde_derive::{Deserialize, Serialize};
|
|
use std::fmt;
|
|
|
|
// Group index, texture index
|
|
type TextureID = (f32, f32);
|
|
|
|
// Copy could be reconsidered, but eh
|
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
|
pub enum Color {
|
|
RGBA(f32, f32, f32, f32),
|
|
// Tiles seamlessly through all of map-space.
|
|
TileTexture(TextureID, ScreenDims),
|
|
// Stretches the entire texture to fit the entire polygon. Rotates from the center of the
|
|
// polygon. Not sure what this means for anything but circles right now. Have to manually
|
|
// fiddle with the original orientation to fix y inversion.
|
|
StretchTexture(TextureID, ScreenDims, Angle),
|
|
// A polygon with UV coordinates for each point must be used.
|
|
CustomUVTexture(TextureID),
|
|
// TODO Figure out how to pack more data into this.
|
|
HatchingStyle1,
|
|
HatchingStyle2,
|
|
}
|
|
|
|
impl fmt::Display for Color {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
Color::RGBA(r, g, b, a) => write!(f, "Color(r={}, g={}, b={}, a={})", r, g, b, a),
|
|
Color::TileTexture(id, dims) => write!(
|
|
f,
|
|
"Color::TileTexture({}:{}, width={}, height={})",
|
|
id.0, id.1, dims.width, dims.height
|
|
),
|
|
Color::StretchTexture(id, dims, angle) => write!(
|
|
f,
|
|
"Color::StretchTexture({}:{}, width={}, height={}, {})",
|
|
id.0, id.1, dims.width, dims.height, angle
|
|
),
|
|
Color::CustomUVTexture(id) => write!(f, "Color::CustomUVTexture({}:{})", id.0, id.1),
|
|
Color::HatchingStyle1 => write!(f, "Color::HatchingStyle1"),
|
|
Color::HatchingStyle2 => write!(f, "Color::HatchingStyle2"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Color {
|
|
// TODO Won't this confuse the shader? :P
|
|
pub const INVISIBLE: Color = Color::rgba_f(1.0, 0.0, 0.0, 0.0);
|
|
pub const BLACK: Color = Color::rgb_f(0.0, 0.0, 0.0);
|
|
pub const WHITE: Color = Color::rgb_f(1.0, 1.0, 1.0);
|
|
pub const RED: Color = Color::rgb_f(1.0, 0.0, 0.0);
|
|
pub const GREEN: Color = Color::rgb_f(0.0, 1.0, 0.0);
|
|
pub const BLUE: Color = Color::rgb_f(0.0, 0.0, 1.0);
|
|
pub const CYAN: Color = Color::rgb_f(0.0, 1.0, 1.0);
|
|
pub const YELLOW: Color = Color::rgb_f(1.0, 1.0, 0.0);
|
|
pub const PURPLE: Color = Color::rgb_f(0.5, 0.0, 0.5);
|
|
pub const PINK: Color = Color::rgb_f(1.0, 0.41, 0.71);
|
|
pub const ORANGE: Color = Color::rgb_f(1.0, 0.55, 0.0);
|
|
|
|
// TODO should assert stuff about the inputs
|
|
|
|
// TODO Once f32 can be used in const fn, make these const fn too and clean up call sites
|
|
// dividing by 255.0. https://github.com/rust-lang/rust/issues/57241
|
|
pub fn rgb(r: usize, g: usize, b: usize) -> Color {
|
|
Color::rgba(r, g, b, 1.0)
|
|
}
|
|
|
|
pub const fn rgb_f(r: f32, g: f32, b: f32) -> Color {
|
|
Color::RGBA(r, g, b, 1.0)
|
|
}
|
|
|
|
pub fn rgba(r: usize, g: usize, b: usize, a: f32) -> Color {
|
|
Color::RGBA(
|
|
(r as f32) / 255.0,
|
|
(g as f32) / 255.0,
|
|
(b as f32) / 255.0,
|
|
a,
|
|
)
|
|
}
|
|
|
|
pub const fn rgba_f(r: f32, g: f32, b: f32, a: f32) -> Color {
|
|
Color::RGBA(r, g, b, a)
|
|
}
|
|
|
|
pub const fn grey(f: f32) -> Color {
|
|
Color::RGBA(f, f, f, 1.0)
|
|
}
|
|
|
|
pub fn alpha(&self, a: f32) -> Color {
|
|
match self {
|
|
Color::RGBA(r, g, b, _) => Color::RGBA(*r, *g, *b, a),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
pub fn fade(&self, factor: f32) -> Color {
|
|
match self {
|
|
Color::RGBA(r, g, b, a) => Color::RGBA(*r / factor, *g / factor, *b / factor, *a),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
pub fn hex(raw: &str) -> Color {
|
|
// Skip the leading '#'
|
|
let r = usize::from_str_radix(&raw[1..3], 16).unwrap();
|
|
let g = usize::from_str_radix(&raw[3..5], 16).unwrap();
|
|
let b = usize::from_str_radix(&raw[5..7], 16).unwrap();
|
|
Color::rgb(r, g, b)
|
|
}
|
|
|
|
pub fn rotate(&self, angle: Angle) -> Color {
|
|
match self {
|
|
Color::StretchTexture(id, dims, _) => Color::StretchTexture(*id, *dims, angle),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
pub fn texture_dims(&self) -> ScreenDims {
|
|
match self {
|
|
Color::TileTexture(_, dims) => *dims,
|
|
Color::StretchTexture(_, dims, _) => *dims,
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
}
|