maplibre/raster/
render_commands.rs

1use crate::{
2    raster::resource::RasterResources,
3    render::{
4        eventually::{Eventually, Eventually::Initialized},
5        render_phase::{LayerItem, PhaseItem, RenderCommand, RenderCommandResult},
6        resource::TrackedRenderPass,
7        tile_view_pattern::WgpuTileViewPattern,
8    },
9    tcs::world::World,
10};
11
12pub struct SetRasterTilePipeline;
13impl<P: PhaseItem> RenderCommand<P> for SetRasterTilePipeline {
14    fn render<'w>(
15        world: &'w World,
16        _item: &P,
17        pass: &mut TrackedRenderPass<'w>,
18    ) -> RenderCommandResult {
19        let Some(Initialized(raster_resources)) =
20            world.resources.get::<Eventually<RasterResources>>()
21        else {
22            return RenderCommandResult::Failure;
23        };
24
25        pass.set_render_pipeline(raster_resources.pipeline());
26        RenderCommandResult::Success
27    }
28}
29
30pub struct SetRasterViewBindGroup<const I: usize>;
31impl<const I: usize> RenderCommand<LayerItem> for SetRasterViewBindGroup<I> {
32    fn render<'w>(
33        world: &'w World,
34        item: &LayerItem,
35        pass: &mut TrackedRenderPass<'w>,
36    ) -> RenderCommandResult {
37        let Some(Initialized(raster_resources)) =
38            world.resources.get::<Eventually<RasterResources>>()
39        else {
40            return RenderCommandResult::Failure;
41        };
42
43        let Some(bind_group) = raster_resources.get_bound_texture(&item.tile.coords) else {
44            return RenderCommandResult::Failure;
45        };
46
47        pass.set_bind_group(0, bind_group, &[]);
48        RenderCommandResult::Success
49    }
50}
51
52pub struct DrawRasterTile;
53impl RenderCommand<LayerItem> for DrawRasterTile {
54    fn render<'w>(
55        world: &'w World,
56        item: &LayerItem,
57        pass: &mut TrackedRenderPass<'w>,
58    ) -> RenderCommandResult {
59        let Some(Initialized(tile_view_pattern)) =
60            world.resources.get::<Eventually<WgpuTileViewPattern>>()
61        else {
62            return RenderCommandResult::Failure;
63        };
64
65        let source_shape = &item.source_shape;
66
67        let reference = source_shape.coords().stencil_reference_value_3d() as u32;
68
69        pass.set_stencil_reference(reference);
70
71        let tile_view_pattern_buffer = source_shape
72            .buffer_range()
73            .expect("tile_view_pattern needs to be uploaded first"); // FIXME tcs
74        pass.set_vertex_buffer(
75            0,
76            tile_view_pattern.buffer().slice(tile_view_pattern_buffer),
77        );
78
79        let tile_view_pattern_buffer = source_shape
80            .buffer_range()
81            .expect("tile_view_pattern needs to be uploaded first"); // FIXME tcs
82
83        // FIXME tcs: I passin random data here right now, but instead we need the correct metadata here
84        pass.set_vertex_buffer(
85            1,
86            tile_view_pattern.buffer().slice(tile_view_pattern_buffer),
87        );
88
89        const TILE_MASK_SHADER_VERTICES: u32 = 6;
90        pass.draw(0..TILE_MASK_SHADER_VERTICES, 0..1);
91
92        RenderCommandResult::Success
93    }
94}
95
96pub type DrawRasterTiles = (
97    SetRasterTilePipeline,
98    SetRasterViewBindGroup<0>,
99    DrawRasterTile,
100);