maplibre/sdf/
resource_system.rs1use wgpu::util::{DeviceExt, TextureDataOrder};
3
4use crate::{
5 context::MapContext,
6 render::{
7 eventually::Eventually,
8 resource::{RenderPipeline, TilePipeline},
9 shaders,
10 shaders::Shader,
11 RenderResources, Renderer,
12 },
13 sdf::{resource::GlyphTexture, text::GlyphSet, SymbolBufferPool, SymbolPipeline},
14 tcs::system::{SystemError, SystemResult},
15 vector::resource::BufferPool,
16};
17
18pub fn resource_system(
19 MapContext {
20 world,
21 renderer:
22 Renderer {
23 device,
24 queue,
25 resources: RenderResources { surface, .. },
26 settings,
27 ..
28 },
29 ..
30 }: &mut MapContext,
31) -> SystemResult {
32 let Some((
33 symbol_buffer_pool,
34 symbol_pipeline,
35 glyph_texture_sampler,
36 glyph_texture_bind_group,
37 )) = world.resources.query_mut::<(
38 &mut Eventually<SymbolBufferPool>,
39 &mut Eventually<SymbolPipeline>,
40 &mut Eventually<(wgpu::Texture, wgpu::Sampler)>,
41 &mut Eventually<GlyphTexture>,
42 )>()
43 else {
44 return Err(SystemError::Dependencies);
45 };
46
47 symbol_buffer_pool.initialize(|| BufferPool::from_device(device));
48
49 symbol_pipeline.initialize(|| {
50 let tile_shader = shaders::SymbolShader {
51 format: surface.surface_format(),
52 };
53
54 let pipeline = TilePipeline::new(
55 "symbol_pipeline".into(),
56 *settings,
57 tile_shader.describe_vertex(),
58 tile_shader.describe_fragment(),
59 false,
60 false,
61 true, false,
63 surface.is_multisampling_supported(settings.msaa),
64 false,
65 true,
66 )
67 .describe_render_pipeline()
68 .initialize(device);
69
70 let (texture, sampler) = glyph_texture_sampler.initialize(|| {
71 let data = include_bytes!("../../../data/0-255.pbf");
72 let glyphs = GlyphSet::try_from(data.as_slice()).unwrap();
73
74 let (width, height) = glyphs.get_texture_dimensions();
75
76 let texture = device.create_texture_with_data(
77 queue,
78 &wgpu::TextureDescriptor {
79 label: Some("Glyph Texture"),
80 size: wgpu::Extent3d {
81 width: width as _,
82 height: height as _,
83 depth_or_array_layers: 1,
84 },
85 mip_level_count: 1,
86 sample_count: 1,
87 dimension: wgpu::TextureDimension::D2,
88 format: wgpu::TextureFormat::R8Unorm,
89 usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
90 view_formats: &[wgpu::TextureFormat::R8Unorm], },
92 TextureDataOrder::LayerMajor, glyphs.get_texture_bytes(),
94 );
95
96 let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
97 mag_filter: wgpu::FilterMode::Linear,
99 min_filter: wgpu::FilterMode::Linear,
100 ..Default::default()
101 });
102
103 (texture, sampler)
104 });
105
106 glyph_texture_bind_group.initialize(|| {
107 GlyphTexture::from_device(device, texture, sampler, &pipeline.get_bind_group_layout(0))
108 });
109
110 SymbolPipeline(pipeline)
111 });
112 Ok(())
113}