mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
First time rendering two tiles
This commit is contained in:
parent
62e29042a7
commit
aeba8afc31
@ -33,7 +33,7 @@ pub fn create_map_render_pipeline_description<'a>(
|
||||
compare: wgpu::CompareFunction::Always, // Allow ALL values to update the stencil
|
||||
fail_op: wgpu::StencilOperation::Keep,
|
||||
depth_fail_op: wgpu::StencilOperation::Keep, // This is used when the depth test already failed
|
||||
pass_op: wgpu::StencilOperation::IncrementClamp,
|
||||
pass_op: wgpu::StencilOperation::Replace,
|
||||
}
|
||||
} else {
|
||||
wgpu::StencilFaceState {
|
||||
|
||||
@ -40,9 +40,11 @@ fn main(
|
||||
[[location(2)]] a_prim_id: u32,
|
||||
[[builtin(instance_index)]] instance_idx: u32 // instance_index is used when we have multiple instances of the same "object"
|
||||
) -> VertexOutput {
|
||||
var prim: PrimitiveUniform = u_primitives.primitives[a_prim_id + instance_idx];
|
||||
var prim: PrimitiveUniform = u_primitives.primitives[a_prim_id];
|
||||
var z = 0.0;
|
||||
var world_pos = a_position + a_normal * prim.width;
|
||||
|
||||
var mask_offset = vec2<f32>(f32(instance_idx) * 4096.0, 0.0);
|
||||
var world_pos = a_position + mask_offset + prim.translate + a_normal * prim.width;
|
||||
|
||||
var position = globals.camera.view_proj * vec4<f32>(world_pos, z, 1.0);
|
||||
|
||||
|
||||
@ -38,9 +38,15 @@ impl Default for SceneParams {
|
||||
}
|
||||
}
|
||||
|
||||
const INDEX_FORMAT: wgpu::IndexFormat = wgpu::IndexFormat::Uint32;
|
||||
type IndexDataType = u32; // Must match INDEX_FORMAT
|
||||
|
||||
const PRIM_BUFFER_LEN: usize = 256;
|
||||
const STROKE_PRIM_ID: u32 = 0;
|
||||
const FILL_PRIM_ID: u32 = 1;
|
||||
const SECOND_TILE_FILL_PRIM_ID: u32 = 2;
|
||||
const MASK_FILL_PRIM_ID: u32 = 3;
|
||||
const SECOND_TILE_STROKE_PRIM_ID: u32 = 5;
|
||||
|
||||
pub struct State {
|
||||
device: wgpu::Device,
|
||||
@ -69,6 +75,8 @@ pub struct State {
|
||||
indices_uniform_buffer: wgpu::Buffer,
|
||||
tile_fill_range: Range<u32>,
|
||||
tile_stroke_range: Range<u32>,
|
||||
tile2_fill_range: Range<u32>,
|
||||
tile2_stroke_range: Range<u32>,
|
||||
|
||||
tile_mask_vertex_uniform_buffer: wgpu::Buffer,
|
||||
tile_mask_indices_uniform_buffer: wgpu::Buffer,
|
||||
@ -98,10 +106,18 @@ impl SceneParams {
|
||||
|
||||
// Stroke primitive
|
||||
cpu_primitives[STROKE_PRIM_ID as usize] =
|
||||
PrimitiveUniform::new([0.0, 0.0, 0.0, 1.0], [0.0, 0.0], 0, 1.0, 0.0, 1.0);
|
||||
PrimitiveUniform::new([1.0, 0.0, 1.0, 1.0], [0.0, 0.0], 0, 1.0, 0.0, 1.0);
|
||||
cpu_primitives[SECOND_TILE_STROKE_PRIM_ID as usize] =
|
||||
PrimitiveUniform::new([0.5, 0.8, 0.1, 1.0], [4096.0, 0.0], 0, 1.0, 0.0, 1.0);
|
||||
// Main fill primitive
|
||||
cpu_primitives[FILL_PRIM_ID as usize] =
|
||||
PrimitiveUniform::new([0.0, 0.0, 1.0, 1.0], [0.0, 0.0], 0, 1.0, 0.0, 1.0);
|
||||
cpu_primitives[SECOND_TILE_FILL_PRIM_ID as usize] =
|
||||
PrimitiveUniform::new([0.0, 1.0, 1.0, 1.0], [4096.0, 0.0], 0, 1.0, 0.0, 1.0);
|
||||
|
||||
cpu_primitives[MASK_FILL_PRIM_ID as usize] =
|
||||
PrimitiveUniform::new([0.0, 0.0, 1.0, 1.0], [0.0, 0.0], 0, 1.0, 0.0, 1.0);
|
||||
|
||||
|
||||
Self {
|
||||
cpu_primitives,
|
||||
@ -116,16 +132,25 @@ impl State {
|
||||
|
||||
let size = window.inner_size();
|
||||
|
||||
let mut geometry: VertexBuffers<GpuVertexUniform, u16> = VertexBuffers::new();
|
||||
let mut geometry: VertexBuffers<GpuVertexUniform, IndexDataType> = VertexBuffers::new();
|
||||
|
||||
println!("Using static database from {}", static_database::get_source_path());
|
||||
|
||||
let tile = parse_tile_reader(&mut Cursor::new(static_database::get_tile(2179, 1421,12).unwrap().contents())).expect("failed to load tile");
|
||||
let (tile_stroke_range, tile_fill_range) = (
|
||||
tile.tesselate_stroke(&mut geometry, STROKE_PRIM_ID),
|
||||
//tile.empty_range(&mut geometry, STROKE_PRIM_ID),
|
||||
tile.tesselate_fill(&mut geometry, FILL_PRIM_ID),
|
||||
);
|
||||
|
||||
// tile right to it
|
||||
let tile = parse_tile_reader(&mut Cursor::new(static_database::get_tile(2180, 1421,12).unwrap().contents())).expect("failed to load tile");
|
||||
let (tile2_stroke_range, tile2_fill_range) = (
|
||||
tile.tesselate_stroke(&mut geometry, SECOND_TILE_STROKE_PRIM_ID),
|
||||
//tile.empty_range(&mut geometry, STROKE_PRIM_ID),
|
||||
tile.tesselate_fill(&mut geometry, SECOND_TILE_FILL_PRIM_ID),
|
||||
);
|
||||
|
||||
// create an instance
|
||||
let instance = wgpu::Instance::new(wgpu::Backends::all());
|
||||
|
||||
@ -177,9 +202,9 @@ impl State {
|
||||
usage: wgpu::BufferUsages::INDEX,
|
||||
});
|
||||
|
||||
let mut tile_mask_geometry: VertexBuffers<GpuVertexUniform, u16> = VertexBuffers::new();
|
||||
let mut tile_mask_geometry: VertexBuffers<GpuVertexUniform, IndexDataType> = VertexBuffers::new();
|
||||
let tile_mask = TileMask();
|
||||
let tile_mask_range = tile_mask.tesselate_fill(&mut tile_mask_geometry, FILL_PRIM_ID);
|
||||
let tile_mask_range = tile_mask.tesselate_fill(&mut tile_mask_geometry, MASK_FILL_PRIM_ID);
|
||||
let tile_mask_vertex_uniform_buffer =
|
||||
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: None,
|
||||
@ -370,12 +395,14 @@ impl State {
|
||||
tile_mask_vertex_uniform_buffer,
|
||||
fps_meter: FPSMeter::new(),
|
||||
tile_stroke_range,
|
||||
tile2_fill_range,
|
||||
tile_mask_indices_uniform_buffer,
|
||||
tile_mask_range,
|
||||
camera,
|
||||
projection,
|
||||
camera_controller,
|
||||
mouse_pressed: false,
|
||||
tile2_stroke_range
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,10 +556,10 @@ impl State {
|
||||
{
|
||||
// Increment stencil
|
||||
pass.set_pipeline(&self.mask_pipeline);
|
||||
//pass.set_stencil_reference(0);
|
||||
pass.set_stencil_reference(1);
|
||||
pass.set_index_buffer(
|
||||
self.tile_mask_indices_uniform_buffer.slice(..),
|
||||
wgpu::IndexFormat::Uint16,
|
||||
INDEX_FORMAT,
|
||||
);
|
||||
pass.set_vertex_buffer(0, self.tile_mask_vertex_uniform_buffer.slice(..));
|
||||
pass.draw_indexed(self.tile_mask_range.clone(), 0, 0..1);
|
||||
@ -542,12 +569,34 @@ impl State {
|
||||
pass.set_stencil_reference(1);
|
||||
pass.set_index_buffer(
|
||||
self.indices_uniform_buffer.slice(..),
|
||||
wgpu::IndexFormat::Uint16,
|
||||
INDEX_FORMAT,
|
||||
);
|
||||
pass.set_vertex_buffer(0, self.vertex_uniform_buffer.slice(..));
|
||||
pass.draw_indexed(self.tile_fill_range.clone(), 0, 0..1);
|
||||
pass.draw_indexed(self.tile_stroke_range.clone(), 0, 0..1);
|
||||
}
|
||||
{
|
||||
// Increment stencil
|
||||
pass.set_pipeline(&self.mask_pipeline);
|
||||
pass.set_stencil_reference(2);
|
||||
pass.set_index_buffer(
|
||||
self.tile_mask_indices_uniform_buffer.slice(..),
|
||||
INDEX_FORMAT,
|
||||
);
|
||||
pass.set_vertex_buffer(0, self.tile_mask_vertex_uniform_buffer.slice(..));
|
||||
pass.draw_indexed(self.tile_mask_range.clone(), 0, 1..2);
|
||||
}
|
||||
{
|
||||
pass.set_pipeline(&self.render_pipeline);
|
||||
pass.set_stencil_reference(2);
|
||||
pass.set_index_buffer(
|
||||
self.indices_uniform_buffer.slice(..),
|
||||
INDEX_FORMAT,
|
||||
);
|
||||
pass.set_vertex_buffer(0, self.vertex_uniform_buffer.slice(..));
|
||||
pass.draw_indexed(self.tile2_fill_range.clone(), 0, 0..1);
|
||||
pass.draw_indexed(self.tile2_stroke_range.clone(), 0, 0..1);
|
||||
}
|
||||
}
|
||||
|
||||
self.queue.submit(Some(encoder.finish()));
|
||||
@ -568,13 +617,13 @@ impl State {
|
||||
|
||||
// Animate the strokes of primitive
|
||||
scene.cpu_primitives[STROKE_PRIM_ID as usize].width = scene.stroke_width;
|
||||
scene.cpu_primitives[STROKE_PRIM_ID as usize].color = [
|
||||
/* scene.cpu_primitives[STROKE_PRIM_ID as usize].color = [
|
||||
(time_secs * 0.8 - 1.6).sin() * 0.1 + 0.1,
|
||||
(time_secs * 0.5 - 1.6).sin() * 0.1 + 0.1,
|
||||
(time_secs - 1.6).sin() * 0.1 + 0.1,
|
||||
1.0,
|
||||
];
|
||||
|
||||
*/
|
||||
self.fps_meter.update_and_print()
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ use lyon::tessellation::{
|
||||
BuffersBuilder, FillOptions, FillVertexConstructor, StrokeOptions, StrokeVertexConstructor,
|
||||
VertexBuffers,
|
||||
};
|
||||
use lyon::tessellation::geometry_builder::MaxIndex;
|
||||
use lyon_path::builder::SvgPathBuilder;
|
||||
use lyon_path::Path;
|
||||
|
||||
@ -17,9 +18,15 @@ use super::shader_ffi::GpuVertexUniform;
|
||||
|
||||
const DEFAULT_TOLERANCE: f32 = 0.02;
|
||||
|
||||
pub trait Tesselated {
|
||||
fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertexUniform, u16>, prim_id: u32) -> Range<u32>;
|
||||
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertexUniform, u16>, prim_id: u32) -> Range<u32>;
|
||||
pub trait Tesselated<OutputIndex: std::ops::Add> {
|
||||
fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertexUniform, OutputIndex>, prim_id: u32) -> Range<u32>;
|
||||
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertexUniform, OutputIndex>, prim_id: u32) -> Range<u32>;
|
||||
|
||||
fn empty_range(&self, buffer: &mut VertexBuffers<GpuVertexUniform, OutputIndex>,
|
||||
_prim_id: u32) -> Range<u32> {
|
||||
let initial_indices_count = buffer.indices.len() as u32;
|
||||
(initial_indices_count..initial_indices_count)
|
||||
}
|
||||
}
|
||||
|
||||
/// This vertex constructor forwards the positions and normals provided by the
|
||||
@ -45,11 +52,12 @@ impl StrokeVertexConstructor<GpuVertexUniform> for WithId {
|
||||
|
||||
fn build_path(
|
||||
tile: &Tile,
|
||||
fill: bool
|
||||
) -> Path {
|
||||
let mut tile_builder = Path::builder().with_svg();
|
||||
|
||||
for layer in tile.layers() {
|
||||
if layer.name() != "water" {
|
||||
if layer.name() != "transportation" {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -79,24 +87,26 @@ fn build_path(
|
||||
}
|
||||
}
|
||||
Geometry::GeometryLineString(polygon) => {
|
||||
for command in &polygon.commands {
|
||||
match command {
|
||||
Command::MoveTo(cmd) => {
|
||||
tile_builder.relative_move_to(lyon_path::math::vector(
|
||||
cmd.x as f32,
|
||||
cmd.y as f32,
|
||||
));
|
||||
}
|
||||
Command::LineTo(cmd) => {
|
||||
tile_builder.relative_line_to(lyon_path::math::vector(
|
||||
cmd.x as f32,
|
||||
cmd.y as f32,
|
||||
));
|
||||
}
|
||||
Command::Close => {
|
||||
panic!("error")
|
||||
}
|
||||
};
|
||||
if !fill {
|
||||
for command in &polygon.commands {
|
||||
match command {
|
||||
Command::MoveTo(cmd) => {
|
||||
tile_builder.relative_move_to(lyon_path::math::vector(
|
||||
cmd.x as f32,
|
||||
cmd.y as f32,
|
||||
));
|
||||
}
|
||||
Command::LineTo(cmd) => {
|
||||
tile_builder.relative_line_to(lyon_path::math::vector(
|
||||
cmd.x as f32,
|
||||
cmd.y as f32,
|
||||
));
|
||||
}
|
||||
Command::Close => {
|
||||
panic!("error")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -108,18 +118,17 @@ fn build_path(
|
||||
tile_builder.build()
|
||||
}
|
||||
|
||||
|
||||
impl Tesselated for Tile {
|
||||
impl<OutputIndex: std::ops::Add + std::convert::From<lyon::lyon_tessellation::VertexId> + MaxIndex> Tesselated<OutputIndex> for Tile {
|
||||
fn tesselate_stroke(
|
||||
&self,
|
||||
buffer: &mut VertexBuffers<GpuVertexUniform, u16>,
|
||||
buffer: &mut VertexBuffers<GpuVertexUniform, OutputIndex>,
|
||||
prim_id: u32,
|
||||
) -> Range<u32> {
|
||||
let mut tesselator = StrokeTessellator::new();
|
||||
|
||||
let initial_indices_count = buffer.indices.len();
|
||||
|
||||
let tile_path = build_path(self);
|
||||
let tile_path = build_path(self, false);
|
||||
|
||||
tesselator
|
||||
.tessellate_path(
|
||||
@ -132,12 +141,12 @@ impl Tesselated for Tile {
|
||||
initial_indices_count as u32..buffer.indices.len() as u32
|
||||
}
|
||||
|
||||
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertexUniform, u16>, prim_id: u32) -> Range<u32> {
|
||||
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertexUniform, OutputIndex>, prim_id: u32) -> Range<u32> {
|
||||
let mut tesselator = FillTessellator::new();
|
||||
|
||||
let initial_indices_count = buffer.indices.len();
|
||||
|
||||
let tile_path = build_path(self);
|
||||
let tile_path = build_path(self, true);
|
||||
|
||||
tesselator
|
||||
.tessellate_path(
|
||||
@ -153,8 +162,8 @@ impl Tesselated for Tile {
|
||||
|
||||
pub struct RustLogo();
|
||||
|
||||
impl Tesselated for RustLogo {
|
||||
fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertexUniform, u16>, prim_id: u32) -> Range<u32> {
|
||||
impl<OutputIndex: std::ops::Add + std::convert::From<lyon::lyon_tessellation::VertexId> + MaxIndex> Tesselated<OutputIndex> for RustLogo {
|
||||
fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertexUniform, OutputIndex>, prim_id: u32) -> Range<u32> {
|
||||
let mut stroke_tess = StrokeTessellator::new();
|
||||
|
||||
let initial_indices_count = buffer.indices.len();
|
||||
@ -175,7 +184,7 @@ impl Tesselated for RustLogo {
|
||||
initial_indices_count as u32..buffer.indices.len() as u32
|
||||
}
|
||||
|
||||
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertexUniform, u16>, prim_id: u32) -> Range<u32> {
|
||||
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertexUniform, OutputIndex>, prim_id: u32) -> Range<u32> {
|
||||
let mut fill_tess = FillTessellator::new();
|
||||
|
||||
let initial_indices_count = buffer.indices.len();
|
||||
@ -203,12 +212,12 @@ const EXTENT: f32 = 4096.0;
|
||||
|
||||
pub struct TileMask();
|
||||
|
||||
impl Tesselated for TileMask {
|
||||
fn tesselate_stroke(&self, _buffer: &mut VertexBuffers<GpuVertexUniform, u16>, _prim_id: u32) -> Range<u32> {
|
||||
impl Tesselated<u32> for TileMask {
|
||||
fn tesselate_stroke(&self, _buffer: &mut VertexBuffers<GpuVertexUniform, u32>, _prim_id: u32) -> Range<u32> {
|
||||
0..0
|
||||
}
|
||||
|
||||
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertexUniform, u16>, prim_id: u32) -> Range<u32> {
|
||||
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertexUniform, u32>, prim_id: u32) -> Range<u32> {
|
||||
let initial_indices_count = buffer.indices.len();
|
||||
|
||||
buffer.vertices = vec![
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user