Add a color type

This commit is contained in:
Maximilian Ammann 2022-03-15 14:56:38 +01:00
parent 32a48fc46d
commit a650676f23
7 changed files with 284 additions and 67 deletions

153
Cargo.lock generated
View File

@ -14,7 +14,7 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom",
"getrandom 0.2.5",
"once_cell",
"version_check",
]
@ -488,6 +488,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "cint"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d83feae28854d73f33659f9018546157422ddf5b84264ce171a766d8547d77b"
[[package]]
name = "clap"
version = "2.34.0"
@ -756,6 +762,17 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "csscolorparser"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2fb3bd93ef32553e3d5b9f8020028f41ac64ff8a230033d5d548b8222d21fbe"
dependencies = [
"cint",
"phf",
"serde",
]
[[package]]
name = "csv"
version = "1.1.6"
@ -1139,6 +1156,17 @@ dependencies = [
"version_check",
]
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.2.5"
@ -1147,7 +1175,7 @@ checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi",
"wasi 0.10.2+wasi-snapshot-preview1",
]
[[package]]
@ -2029,6 +2057,50 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "phf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
"phf_macros",
"phf_shared",
"proc-macro-hack",
]
[[package]]
name = "phf_generator"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_macros"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
"siphasher",
]
[[package]]
name = "pin-project-lite"
version = "0.2.8"
@ -2088,6 +2160,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "ppv-lite86"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "proc-macro-crate"
version = "1.1.3"
@ -2098,6 +2176,12 @@ dependencies = [
"toml",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
version = "1.0.36"
@ -2147,6 +2231,57 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
"rand_pcg",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[package]]
name = "rand_pcg"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
dependencies = [
"rand_core",
]
[[package]]
name = "range-alloc"
version = "0.1.2"
@ -2590,6 +2725,12 @@ dependencies = [
"libc",
]
[[package]]
name = "siphasher"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
[[package]]
name = "slab"
version = "0.4.5"
@ -2732,6 +2873,8 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
name = "style-spec"
version = "0.1.0"
dependencies = [
"cint",
"csscolorparser",
"serde",
"serde_json",
]
@ -3075,6 +3218,12 @@ dependencies = [
"try-lock",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"

View File

@ -9,7 +9,8 @@ build = "build.rs"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
# csscolorparser = "0.5"
csscolorparser = { version = "0.5", features = ["serde", "cint"]}
cint = "0.2"
[build-dependencies]
serde_json = "1.0"

View File

@ -1,31 +1,32 @@
use csscolorparser::Color;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BackgroundPaint {
#[serde(rename = "background-color")]
#[serde(skip_serializing_if = "Option::is_none")]
pub background_color: Option<String>,
pub background_color: Option<Color>,
// TODO a lot
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct FillPaint {
#[serde(rename = "fill-color")]
#[serde(skip_serializing_if = "Option::is_none")]
pub fill_color: Option<String>,
pub fill_color: Option<Color>,
// TODO a lot
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct LinePaint {
#[serde(rename = "line-color")]
#[serde(skip_serializing_if = "Option::is_none")]
pub line_color: Option<String>,
pub line_color: Option<Color>,
// TODO a lot
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type", content = "paint")]
pub enum LayerPaint {
#[serde(rename = "background")]
@ -36,7 +37,7 @@ pub enum LayerPaint {
Fill(FillPaint),
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StyleLayer {
pub id: String,
#[serde(rename = "type")]

View File

@ -3,3 +3,5 @@ pub mod source;
mod style;
pub use crate::style::*;
pub use cint::*;

View File

@ -1,7 +1,9 @@
use crate::layer::StyleLayer;
use crate::layer::{LayerPaint, LinePaint, StyleLayer};
use crate::source::Source;
use csscolorparser::Color;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::str::FromStr;
#[derive(Serialize, Deserialize, Debug)]
pub struct Style {
@ -20,13 +22,51 @@ impl Default for Style {
metadata: Default::default(),
sources: Default::default(),
layers: vec![
StyleLayer {
id: "park".to_string(),
typ: "fill".to_string(),
maxzoom: None,
minzoom: None,
metadata: None,
paint: Some(LayerPaint::Line(LinePaint {
line_color: Some(Color::from_str("lightgreen").unwrap()),
})),
source: None,
source_layer: Some("park".to_string()),
},
StyleLayer {
id: "lanuse".to_string(),
typ: "fill".to_string(),
maxzoom: None,
minzoom: None,
metadata: None,
paint: Some(LayerPaint::Line(LinePaint {
line_color: Some(Color::from_str("lightgreen").unwrap()),
})),
source: None,
source_layer: Some("landuse".to_string()),
},
StyleLayer {
id: "landcover".to_string(),
typ: "fill".to_string(),
maxzoom: None,
minzoom: None,
metadata: None,
paint: Some(LayerPaint::Line(LinePaint {
line_color: Some(Color::from_str("lightgreen").unwrap()),
})),
source: None,
source_layer: Some("landcover".to_string()),
},
StyleLayer {
id: "transportation".to_string(),
typ: "line".to_string(),
maxzoom: None,
minzoom: None,
metadata: None,
paint: None,
paint: Some(LayerPaint::Line(LinePaint {
line_color: Some(Color::from_str("violet").unwrap()),
})),
source: None,
source_layer: Some("transportation".to_string()),
},
@ -36,7 +76,9 @@ impl Default for Style {
maxzoom: None,
minzoom: None,
metadata: None,
paint: None,
paint: Some(LayerPaint::Line(LinePaint {
line_color: Some(Color::from_str("grey").unwrap()),
})),
source: None,
source_layer: Some("building".to_string()),
},
@ -46,7 +88,9 @@ impl Default for Style {
maxzoom: None,
minzoom: None,
metadata: None,
paint: None,
paint: Some(LayerPaint::Line(LinePaint {
line_color: Some(Color::from_str("blue").unwrap()),
})),
source: None,
source_layer: Some("water".to_string()),
},
@ -56,7 +100,9 @@ impl Default for Style {
maxzoom: None,
minzoom: None,
metadata: None,
paint: None,
paint: Some(LayerPaint::Line(LinePaint {
line_color: Some(Color::from_str("black").unwrap()),
})),
source: None,
source_layer: Some("boundary".to_string()),
},

View File

@ -5,6 +5,7 @@ use std::marker::PhantomData;
use std::mem::size_of;
use std::ops::Range;
use style_spec::layer::StyleLayer;
use wgpu::BufferAddress;
use crate::coords::WorldTileCoords;
@ -138,7 +139,7 @@ impl<Q: Queue<B>, B, V: bytemuck::Pod, I: bytemuck::Pod, TM: bytemuck::Pod, FM:
self.index
.iter()
.filter(|entry| entry.coords == *coords)
.map(|entry| entry.layer_name.clone())
.map(|entry| entry.style_layer.source_layer.as_ref().unwrap().clone())
.collect()
}
@ -151,7 +152,7 @@ impl<Q: Queue<B>, B, V: bytemuck::Pod, I: bytemuck::Pod, TM: bytemuck::Pod, FM:
&mut self,
queue: &Q,
coords: WorldTileCoords,
layer_name: &str,
style_layer: StyleLayer,
geometry: &OverAlignedVertexBuffer<V, I>,
tile_metadata: TM,
feature_metadata: &Vec<FM>,
@ -189,7 +190,7 @@ impl<Q: Queue<B>, B, V: bytemuck::Pod, I: bytemuck::Pod, TM: bytemuck::Pod, FM:
let maybe_entry = IndexEntry {
coords,
layer_name: layer_name.to_string(),
style_layer,
buffer_vertices: self.vertices.make_room(vertices_bytes, &mut self.index),
buffer_indices: self.indices.make_room(indices_bytes, &mut self.index),
usable_indices: geometry.usable_indices as u32,
@ -348,7 +349,7 @@ impl<B> BackingBuffer<B> {
#[derive(Debug)]
pub struct IndexEntry {
pub coords: WorldTileCoords,
pub layer_name: String,
pub style_layer: StyleLayer,
// Range of bytes within the backing buffer for vertices
buffer_vertices: Range<wgpu::BufferAddress>,
// Range of bytes within the backing buffer for indices

View File

@ -7,7 +7,8 @@ use crate::coords::ViewRegion;
use crate::io::scheduler::IOScheduler;
use crate::io::{LayerResult, TileRequest};
use style_spec::Style;
use style_spec::layer::LayerPaint;
use style_spec::{EncodedSrgb, Style};
use wgpu::{Buffer, Limits, Queue};
use winit::dpi::PhysicalSize;
use winit::window::Window;
@ -401,53 +402,68 @@ impl RenderState {
for coords in view_region.iter() {
let loaded_layers = self.buffer_pool.get_loaded_layers(&coords);
let layers = scheduler.get_tessellated_layers_at(&coords, &loaded_layers);
for result in layers {
match result {
LayerResult::UnavailableLayer { .. } => {}
LayerResult::TessellatedLayer {
coords,
feature_indices,
layer_data,
buffer,
..
} => {
let world_coords = coords;
let available_layers = scheduler.get_tessellated_layers_at(&coords, &loaded_layers);
let feature_metadata = layer_data
.features()
.iter()
.enumerate()
.flat_map(|(i, _feature)| {
iter::repeat(ShaderFeatureStyle {
color: match layer_data.name() {
"transportation" => [1.0, 0.0, 0.0, 1.0],
"building" => [0.0, 1.0, 1.0, 1.0],
"boundary" => [0.0, 0.0, 0.0, 1.0],
"water" => [0.0, 0.0, 0.7, 1.0],
"waterway" => [0.0, 0.0, 7.0, 1.0],
_ => [0.0, 0.0, 0.0, 0.0],
},
})
.take(*feature_indices.get(i).unwrap() as usize)
})
.collect::<Vec<_>>();
for style_layer in &self.style.layers {
let source_layer = style_layer.source_layer.as_ref().unwrap();
// We are casting here from 64bit to 32bit, because 32bit is more performant and is
// better supported.
let transform: Matrix4<f32> = (view_proj
* world_coords.transform_for_zoom(self.zoom))
.cast()
.unwrap();
if let Some(result) = available_layers
.iter()
.find(|layer| source_layer.as_str() == layer.layer_name())
{
let color: Option<style_spec::Alpha<EncodedSrgb<f32>>> =
style_layer.paint.as_ref().and_then(|paint| match paint {
LayerPaint::Background(paint) => paint
.background_color
.as_ref()
.map(|color| color.clone().into()),
LayerPaint::Line(paint) => {
paint.line_color.as_ref().map(|color| color.clone().into())
}
LayerPaint::Fill(paint) => {
paint.fill_color.as_ref().map(|color| color.clone().into())
}
});
self.buffer_pool.allocate_tile_geometry(
&self.queue,
match result {
LayerResult::UnavailableLayer { .. } => {}
LayerResult::TessellatedLayer {
coords,
layer_data.name(),
&buffer,
ShaderTileMetadata::new(transform.into()),
&feature_metadata,
);
feature_indices,
layer_data,
buffer,
..
} => {
let world_coords = coords;
let feature_metadata = layer_data
.features()
.iter()
.enumerate()
.flat_map(|(i, _feature)| {
iter::repeat(ShaderFeatureStyle {
color: color.unwrap().into(),
})
.take(*feature_indices.get(i).unwrap() as usize)
})
.collect::<Vec<_>>();
// We are casting here from 64bit to 32bit, because 32bit is more performant and is
// better supported.
let transform: Matrix4<f32> = (view_proj
* world_coords.transform_for_zoom(self.zoom))
.cast()
.unwrap();
self.buffer_pool.allocate_tile_geometry(
&self.queue,
*coords,
style_layer.clone(),
&buffer,
ShaderTileMetadata::new(transform.into()),
&feature_metadata,
);
}
}
}
}
@ -516,9 +532,10 @@ impl RenderState {
pass.set_bind_group(0, &self.bind_group, &[]);
{
for entry in self
.buffer_pool
.index()
let mut to_render = self.buffer_pool.index().collect::<Vec<_>>();
to_render.sort_by(|a, b| a.style_layer.id.partial_cmp(&b.style_layer.id).unwrap());
for entry in to_render
.iter()
.filter(|entry| entry.coords.z == self.visible_z())
{
let reference =