maplibre/sdf/
render_commands.rs1use crate::{
2 render::{
3 eventually::{Eventually, Eventually::Initialized},
4 render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TranslucentItem},
5 resource::TrackedRenderPass,
6 tile_view_pattern::WgpuTileViewPattern,
7 INDEX_FORMAT,
8 },
9 sdf::{resource::GlyphTexture, SymbolBufferPool, SymbolPipeline},
10 tcs::world::World,
11};
12
13pub struct SetSymbolPipeline;
14impl<P: PhaseItem> RenderCommand<P> for SetSymbolPipeline {
15 fn render<'w>(
16 world: &'w World,
17 _item: &P,
18 pass: &mut TrackedRenderPass<'w>,
19 ) -> RenderCommandResult {
20 let Some((Initialized(GlyphTexture { ref bind_group, .. }), Initialized(symbol_pipeline))) =
21 world
22 .resources
23 .query::<(&Eventually<GlyphTexture>, &Eventually<SymbolPipeline>)>()
24 else {
25 return RenderCommandResult::Failure;
26 };
27
28 pass.set_bind_group(0, bind_group, &[]);
29 pass.set_render_pipeline(symbol_pipeline);
30 RenderCommandResult::Success
31 }
32}
33
34pub struct DrawSymbol;
35impl RenderCommand<TranslucentItem> for DrawSymbol {
36 fn render<'w>(
37 world: &'w World,
38 item: &TranslucentItem,
39 pass: &mut TrackedRenderPass<'w>,
40 ) -> RenderCommandResult {
41 let Some((Initialized(symbol_buffer_pool), Initialized(tile_view_pattern))) =
42 world.resources.query::<(
43 &Eventually<SymbolBufferPool>,
44 &Eventually<WgpuTileViewPattern>,
45 )>()
46 else {
47 return RenderCommandResult::Failure;
48 };
49
50 let Some(vector_layers) = symbol_buffer_pool.index().get_layers(item.tile.coords) else {
51 return RenderCommandResult::Failure;
52 };
53
54 let Some(entry) = vector_layers
55 .iter()
56 .find(|entry| entry.style_layer.id == item.style_layer)
57 else {
58 return RenderCommandResult::Failure;
59 };
60
61 let source_shape = &item.source_shape;
62
63 let tile_view_pattern_buffer = source_shape
64 .buffer_range()
65 .expect("tile_view_pattern needs to be uploaded first"); let reference = source_shape.coords().stencil_reference_value_3d() as u32;
69
70 tracing::trace!(
71 "Drawing layer {:?} at {}",
72 entry.style_layer.source_layer,
73 entry.coords
74 );
75
76 let index_range = entry.indices_buffer_range();
77
78 if index_range.is_empty() {
79 tracing::error!("Tried to draw a vector tile without any vertices");
80 return RenderCommandResult::Failure;
81 }
82
83 pass.set_stencil_reference(reference);
84
85 pass.set_index_buffer(
86 symbol_buffer_pool.indices().slice(index_range),
87 INDEX_FORMAT,
88 );
89 pass.set_vertex_buffer(
90 0,
91 symbol_buffer_pool
92 .vertices()
93 .slice(entry.vertices_buffer_range()),
94 );
95 pass.set_vertex_buffer(
96 1,
97 tile_view_pattern.buffer().slice(tile_view_pattern_buffer),
98 );
99 pass.set_vertex_buffer(
100 2,
101 symbol_buffer_pool
102 .metadata()
103 .slice(entry.layer_metadata_buffer_range()),
104 );
105 pass.draw_indexed(entry.indices_range(), 0, 0..1);
113 RenderCommandResult::Success
114 }
115}
116
117pub type DrawSymbols = (SetSymbolPipeline, DrawSymbol);