mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Enable stencil and render rust logo into map
This commit is contained in:
parent
3f4beab87f
commit
add96bbf91
@ -6,7 +6,6 @@ edition = "2021"
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
||||||
web-webgl = [ "wgpu/webgl" ]
|
web-webgl = [ "wgpu/webgl" ]
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
|
|||||||
@ -20,6 +20,9 @@ async fn setup(window: Window, event_loop: EventLoop<()>) {
|
|||||||
|
|
||||||
let mut state = State::new(&window).await;
|
let mut state = State::new(&window).await;
|
||||||
|
|
||||||
|
// Important: This kick-starts the rendering loop
|
||||||
|
// window.request_redraw();
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use wgpu::{FragmentState, PipelineLayout, RenderPipelineDescriptor, VertexState};
|
use wgpu::{FragmentState, PipelineLayout, RenderPipelineDescriptor, VertexState};
|
||||||
|
|
||||||
|
use super::texture::DEPTH_TEXTURE_FORMAT;
|
||||||
|
|
||||||
pub fn create_map_render_pipeline_description<'a>(
|
pub fn create_map_render_pipeline_description<'a>(
|
||||||
pipeline_layout: &'a PipelineLayout,
|
pipeline_layout: &'a PipelineLayout,
|
||||||
@ -22,13 +23,23 @@ pub fn create_map_render_pipeline_description<'a>(
|
|||||||
conservative: false,
|
conservative: false,
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth32Float,
|
format: DEPTH_TEXTURE_FORMAT,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: true,
|
||||||
depth_compare: wgpu::CompareFunction::Greater,
|
depth_compare: wgpu::CompareFunction::Greater,
|
||||||
stencil: wgpu::StencilState {
|
stencil: wgpu::StencilState {
|
||||||
front: wgpu::StencilFaceState::IGNORE,
|
front: wgpu::StencilFaceState {
|
||||||
back: wgpu::StencilFaceState::IGNORE,
|
compare: wgpu::CompareFunction::Equal,
|
||||||
read_mask: 0,
|
fail_op: wgpu::StencilOperation::Keep,
|
||||||
|
depth_fail_op: wgpu::StencilOperation::Keep,
|
||||||
|
pass_op: wgpu::StencilOperation::IncrementClamp,
|
||||||
|
},
|
||||||
|
back: wgpu::StencilFaceState {
|
||||||
|
compare: wgpu::CompareFunction::Equal,
|
||||||
|
fail_op: wgpu::StencilOperation::Keep,
|
||||||
|
depth_fail_op: wgpu::StencilOperation::Keep,
|
||||||
|
pass_op: wgpu::StencilOperation::IncrementClamp,
|
||||||
|
},
|
||||||
|
read_mask: 1,
|
||||||
write_mask: 0,
|
write_mask: 0,
|
||||||
},
|
},
|
||||||
bias: wgpu::DepthBiasState::default(),
|
bias: wgpu::DepthBiasState::default(),
|
||||||
|
|||||||
@ -9,5 +9,5 @@ pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8
|
|||||||
pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
pub const COLOR_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
||||||
|
|
||||||
// FIXME: This limit is enforced by WebGL. Actually this makes sense!
|
// FIXME: This limit is enforced by WebGL. Actually this makes sense!
|
||||||
// This is usually achieved by _pad attributes in shader_ffi.rs
|
// FIXME: This can also be achieved by _pad attributes in shader_ffi.rs
|
||||||
pub const MIN_BUFFER_SIZE: u64 = 32;
|
pub const MIN_BUFFER_SIZE: u64 = 32;
|
||||||
|
|||||||
@ -1,17 +1,18 @@
|
|||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
use std::num::NonZeroU32;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use lyon::math::Vector;
|
use lyon::math::Vector;
|
||||||
use lyon::tessellation::VertexBuffers;
|
use lyon::tessellation::VertexBuffers;
|
||||||
use vector_tile::{parse_tile_reader};
|
use vector_tile::parse_tile_reader;
|
||||||
|
use wgpu::Extent3d;
|
||||||
use wgpu::util::DeviceExt;
|
use wgpu::util::DeviceExt;
|
||||||
|
|
||||||
use winit::event::{ElementState, KeyboardInput, VirtualKeyCode, WindowEvent};
|
use winit::event::{ElementState, KeyboardInput, VirtualKeyCode, WindowEvent};
|
||||||
|
|
||||||
use winit::window::Window;
|
use winit::window::Window;
|
||||||
|
|
||||||
use crate::fps_meter::FPSMeter;
|
use crate::fps_meter::FPSMeter;
|
||||||
|
|
||||||
use super::multisampling::create_multisampled_framebuffer;
|
use super::multisampling::create_multisampled_framebuffer;
|
||||||
use super::piplines::*;
|
use super::piplines::*;
|
||||||
use super::platform_constants::{COLOR_TEXTURE_FORMAT, MIN_BUFFER_SIZE};
|
use super::platform_constants::{COLOR_TEXTURE_FORMAT, MIN_BUFFER_SIZE};
|
||||||
@ -71,6 +72,7 @@ pub struct State {
|
|||||||
cpu_primitives: Vec<Primitive>,
|
cpu_primitives: Vec<Primitive>,
|
||||||
fill_range: Range<u32>,
|
fill_range: Range<u32>,
|
||||||
stroke_range: Range<u32>,
|
stroke_range: Range<u32>,
|
||||||
|
mask_fill_range: Range<u32>,
|
||||||
|
|
||||||
scene: SceneParams,
|
scene: SceneParams,
|
||||||
}
|
}
|
||||||
@ -87,19 +89,31 @@ impl State {
|
|||||||
|
|
||||||
let mut geometry: VertexBuffers<GpuVertex, u16> = VertexBuffers::new();
|
let mut geometry: VertexBuffers<GpuVertex, u16> = VertexBuffers::new();
|
||||||
|
|
||||||
let (stroke_range, fill_range) = if true {
|
let (stroke_range, fill_range) = {
|
||||||
//let tile = parse_tile("test-data/12-2176-1425.pbf").expect("failed loading tile");
|
//let tile = parse_tile("test-data/12-2176-1425.pbf").expect("failed loading tile");
|
||||||
let tile = parse_tile_reader(&mut Cursor::new(TEST_TILES));
|
let tile = parse_tile_reader(&mut Cursor::new(TEST_TILES));
|
||||||
|
let count_stroke = tile.tesselate_stroke(&mut geometry, stroke_prim_id);
|
||||||
|
let count_fill = 0;
|
||||||
|
|
||||||
|
let start_stroke = 0;
|
||||||
|
let start_fill = start_stroke + count_stroke;
|
||||||
(
|
(
|
||||||
0..tile.tesselate_stroke(&mut geometry, stroke_prim_id),
|
start_stroke..start_fill,
|
||||||
0..0,
|
start_fill..start_fill + count_fill,
|
||||||
)
|
)
|
||||||
} else {
|
};
|
||||||
|
|
||||||
|
let (_, mask_fill_range) = {
|
||||||
let logo = RustLogo();
|
let logo = RustLogo();
|
||||||
let max_index = logo.tesselate_stroke(&mut geometry, stroke_prim_id);
|
//let count_stroke = logo.tesselate_stroke(&mut geometry, stroke_prim_id);
|
||||||
|
//let start_stroke = fill_range.end;
|
||||||
|
let count_stroke = 0;
|
||||||
|
let start_stroke = fill_range.end;
|
||||||
|
let start_fill = start_stroke + count_stroke;
|
||||||
|
let count_fill = logo.tesselate_fill(&mut geometry, fill_prim_id);
|
||||||
(
|
(
|
||||||
0..max_index,
|
start_stroke..start_fill,
|
||||||
max_index..max_index + logo.tesselate_fill(&mut geometry, fill_prim_id),
|
start_fill..start_fill + count_fill,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,7 +134,7 @@ impl State {
|
|||||||
Primitive::new([0.0, 0.0, 0.0, 1.0], [0.0, 0.0], 3, 1.0, 0.0, 1.0);
|
Primitive::new([0.0, 0.0, 0.0, 1.0], [0.0, 0.0], 3, 1.0, 0.0, 1.0);
|
||||||
// Main fill primitive
|
// Main fill primitive
|
||||||
cpu_primitives[fill_prim_id as usize] =
|
cpu_primitives[fill_prim_id as usize] =
|
||||||
Primitive::new([1.0, 1.0, 1.0, 1.0], [0.0, 0.0], 1, 0.0, 0.0, 1.0);
|
Primitive::new([0.0, 0.0, 0.0, 1.0], [0.0, 0.0], 1, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
// create an instance
|
// create an instance
|
||||||
let instance = wgpu::Instance::new(wgpu::Backends::all());
|
let instance = wgpu::Instance::new(wgpu::Backends::all());
|
||||||
@ -138,12 +152,14 @@ impl State {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// create a device and a queue
|
|
||||||
#[cfg(feature = "web-webgl")]
|
|
||||||
let limits = wgpu::Limits::downlevel_webgl2_defaults();
|
|
||||||
#[cfg(not(feature = "web-webgl"))]
|
|
||||||
let limits = wgpu::Limits::default();
|
|
||||||
|
|
||||||
|
let limits = if cfg!(feature = "web-webgl") {
|
||||||
|
wgpu::Limits::downlevel_webgl2_defaults()
|
||||||
|
} else {
|
||||||
|
wgpu::Limits::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
// create a device and a queue
|
||||||
let (device, queue) = adapter
|
let (device, queue) = adapter
|
||||||
.request_device(
|
.request_device(
|
||||||
&wgpu::DeviceDescriptor {
|
&wgpu::DeviceDescriptor {
|
||||||
@ -259,13 +275,36 @@ impl State {
|
|||||||
format: COLOR_TEXTURE_FORMAT,
|
format: COLOR_TEXTURE_FORMAT,
|
||||||
width: size.width,
|
width: size.width,
|
||||||
height: size.height,
|
height: size.height,
|
||||||
present_mode: wgpu::PresentMode::Mailbox,
|
// present_mode: wgpu::PresentMode::Mailbox,
|
||||||
|
present_mode: wgpu::PresentMode::Fifo, // VSync
|
||||||
};
|
};
|
||||||
|
|
||||||
surface.configure(&device, &surface_config);
|
surface.configure(&device, &surface_config);
|
||||||
|
|
||||||
let depth_texture =
|
let depth_texture =
|
||||||
Texture::create_depth_texture(&device, &surface_config, "depth_texture", sample_count);
|
Texture::create_depth_texture(&device, &surface_config, "depth_texture", sample_count);
|
||||||
|
/*
|
||||||
|
let data = [1; 512 * 512] ;
|
||||||
|
|
||||||
|
queue.write_texture(
|
||||||
|
wgpu::ImageCopyTexture {
|
||||||
|
aspect: wgpu::TextureAspect::StencilOnly,
|
||||||
|
texture: &depth_texture.texture,
|
||||||
|
mip_level: 0,
|
||||||
|
origin: wgpu::Origin3d::ZERO,
|
||||||
|
},
|
||||||
|
&data,
|
||||||
|
wgpu::ImageDataLayout {
|
||||||
|
offset: 0,
|
||||||
|
bytes_per_row: NonZeroU32::new(512),
|
||||||
|
rows_per_image: None,
|
||||||
|
},
|
||||||
|
Extent3d {
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
}
|
||||||
|
);*/
|
||||||
|
|
||||||
let multisampled_render_target = if sample_count > 1 {
|
let multisampled_render_target = if sample_count > 1 {
|
||||||
Some(create_multisampled_framebuffer(
|
Some(create_multisampled_framebuffer(
|
||||||
@ -300,6 +339,7 @@ impl State {
|
|||||||
fps_meter: FPSMeter::new(),
|
fps_meter: FPSMeter::new(),
|
||||||
stroke_range,
|
stroke_range,
|
||||||
cpu_primitives,
|
cpu_primitives,
|
||||||
|
mask_fill_range
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,8 +504,11 @@ impl State {
|
|||||||
);
|
);
|
||||||
pass.set_vertex_buffer(0, self.vertex_uniform_buffer.slice(..));
|
pass.set_vertex_buffer(0, self.vertex_uniform_buffer.slice(..));
|
||||||
|
|
||||||
pass.draw_indexed(self.fill_range.clone(), 0, 0..(self.num_instances as u32));
|
//pass.set_stencil_reference(1);
|
||||||
|
//pass.draw_indexed(self.fill_range.clone(), 0, 0..(self.num_instances as u32));
|
||||||
pass.draw_indexed(self.stroke_range.clone(), 0, 0..1);
|
pass.draw_indexed(self.stroke_range.clone(), 0, 0..1);
|
||||||
|
|
||||||
|
pass.draw_indexed(self.mask_fill_range.clone(), 0, 0..1);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.queue.submit(Some(encoder.finish()));
|
self.queue.submit(Some(encoder.finish()));
|
||||||
|
|||||||
@ -44,6 +44,8 @@ impl Tesselated for Tile {
|
|||||||
let mut stroke_tess = StrokeTessellator::new();
|
let mut stroke_tess = StrokeTessellator::new();
|
||||||
let mut tile_builder = Path::builder().with_svg();
|
let mut tile_builder = Path::builder().with_svg();
|
||||||
|
|
||||||
|
let initial_indices_count = buffer.indices.len();
|
||||||
|
|
||||||
for layer in self.layers() {
|
for layer in self.layers() {
|
||||||
if layer.name() != "water" {
|
if layer.name() != "water" {
|
||||||
continue;
|
continue;
|
||||||
@ -112,7 +114,7 @@ impl Tesselated for Tile {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
buffer.indices.len() as u32
|
(buffer.indices.len() - initial_indices_count) as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tesselate_fill(&self, _buffer: &mut VertexBuffers<GpuVertex, u16>, _prim_id: u32) -> u32 {
|
fn tesselate_fill(&self, _buffer: &mut VertexBuffers<GpuVertex, u16>, _prim_id: u32) -> u32 {
|
||||||
@ -126,6 +128,8 @@ impl Tesselated for RustLogo {
|
|||||||
fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> u32 {
|
fn tesselate_stroke(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> u32 {
|
||||||
let mut stroke_tess = StrokeTessellator::new();
|
let mut stroke_tess = StrokeTessellator::new();
|
||||||
|
|
||||||
|
let initial_indices_count = buffer.indices.len();
|
||||||
|
|
||||||
// Build a Path for the rust logo.
|
// Build a Path for the rust logo.
|
||||||
let mut rust_logo_builder = Path::builder().with_svg();
|
let mut rust_logo_builder = Path::builder().with_svg();
|
||||||
build_logo_path(&mut rust_logo_builder);
|
build_logo_path(&mut rust_logo_builder);
|
||||||
@ -139,12 +143,14 @@ impl Tesselated for RustLogo {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
buffer.indices.len() as u32
|
(buffer.indices.len() - initial_indices_count) as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> u32 {
|
fn tesselate_fill(&self, buffer: &mut VertexBuffers<GpuVertex, u16>, prim_id: u32) -> u32 {
|
||||||
let mut fill_tess = FillTessellator::new();
|
let mut fill_tess = FillTessellator::new();
|
||||||
|
|
||||||
|
let initial_indices_count = buffer.indices.len();
|
||||||
|
|
||||||
// Build a Path for the rust logo.
|
// Build a Path for the rust logo.
|
||||||
let mut rust_logo_builder = Path::builder().with_svg();
|
let mut rust_logo_builder = Path::builder().with_svg();
|
||||||
build_logo_path(&mut rust_logo_builder);
|
build_logo_path(&mut rust_logo_builder);
|
||||||
@ -159,6 +165,6 @@ impl Tesselated for RustLogo {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
buffer.indices.len() as u32
|
(buffer.indices.len() - initial_indices_count) as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,9 @@ pub struct Texture {
|
|||||||
pub view: wgpu::TextureView,
|
pub view: wgpu::TextureView,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const DEPTH_TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
|
|
||||||
impl Texture {
|
impl Texture {
|
||||||
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
|
|
||||||
|
|
||||||
pub fn create_depth_texture(
|
pub fn create_depth_texture(
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
@ -23,7 +24,7 @@ impl Texture {
|
|||||||
mip_level_count: 1,
|
mip_level_count: 1,
|
||||||
sample_count,
|
sample_count,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
dimension: wgpu::TextureDimension::D2,
|
||||||
format: wgpu::TextureFormat::Depth32Float,
|
format: DEPTH_TEXTURE_FORMAT,
|
||||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||||
});
|
});
|
||||||
let view = depth_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
let view = depth_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user