rafx_plugins/features/text/
plugin.rs1use rafx::render_feature_renderer_prelude::*;
2
3use super::*;
4use crate::assets::font::FontAsset;
5use crate::phases::UiRenderPhase;
6use hydrate_base::handle::Handle;
7use rafx::assets::MaterialAsset;
8use rafx::renderer::RendererLoadContext;
9use std::path::PathBuf;
10
11pub struct TextStaticResources {
12 pub text_material: Handle<MaterialAsset>,
13 pub default_font: Handle<FontAsset>,
14}
15
16#[derive(Default)]
17pub struct TextRendererPlugin;
18
19#[cfg(feature = "legion")]
20impl TextRendererPlugin {
21 pub fn legion_init(
22 &self,
23 resources: &mut legion::Resources,
24 ) {
25 resources.insert(TextResource::new());
26 }
27
28 pub fn legion_destroy(resources: &mut legion::Resources) {
29 resources.remove::<TextResource>();
30 }
31}
32
33impl RenderFeaturePlugin for TextRendererPlugin {
34 fn add_asset_paths(
35 &self,
36 asset_paths: &mut Vec<PathBuf>,
37 ) {
38 asset_paths.push(PathBuf::from(concat!(
39 env!("CARGO_MANIFEST_DIR"),
40 "/assets"
41 )));
42 }
43
44 fn feature_debug_constants(&self) -> &'static RenderFeatureDebugConstants {
45 super::render_feature_debug_constants()
46 }
47
48 fn feature_index(&self) -> RenderFeatureIndex {
49 super::render_feature_index()
50 }
51
52 fn is_view_relevant(
53 &self,
54 view: &RenderView,
55 ) -> bool {
56 view.phase_is_relevant::<UiRenderPhase>()
57 }
58
59 fn requires_visible_render_objects(&self) -> bool {
60 false
61 }
62
63 fn configure_render_registry(
64 &self,
65 render_registry: RenderRegistryBuilder,
66 ) -> RenderRegistryBuilder {
67 render_registry.register_feature::<TextRenderFeature>()
68 }
69
70 fn initialize_static_resources(
71 &self,
72 renderer_load_context: &RendererLoadContext,
73 asset_manager: &mut AssetManager,
74 asset_resource: &mut AssetResource,
75 _extract_resources: &ExtractResources,
76 render_resources: &mut RenderResources,
77 _upload: &mut RafxTransferUpload,
78 ) -> RafxResult<()> {
79 let text_material = asset_resource
80 .load_artifact_symbol_name::<MaterialAsset>("rafx-plugins://materials/text.material");
81 let default_font = asset_resource
82 .load_artifact_symbol_name::<FontAsset>("rafx-plugins://fonts/mplus-1p-regular.ttf");
83
84 renderer_load_context.wait_for_asset_to_load(
85 render_resources,
86 asset_manager,
87 &text_material,
88 asset_resource,
89 "text material",
90 )?;
91
92 renderer_load_context.wait_for_asset_to_load(
93 render_resources,
94 asset_manager,
95 &default_font,
96 asset_resource,
97 "default font",
98 )?;
99
100 render_resources.insert(TextStaticResources {
101 text_material,
102 default_font,
103 });
104
105 render_resources.insert(FontAtlasCache::default());
106
107 Ok(())
108 }
109
110 fn new_frame_packet(
111 &self,
112 frame_packet_size: &FramePacketSize,
113 ) -> Box<dyn RenderFeatureFramePacket> {
114 Box::new(TextFramePacket::new(
115 self.feature_index(),
116 frame_packet_size,
117 ))
118 }
119
120 fn new_extract_job<'extract>(
121 &self,
122 extract_context: &RenderJobExtractContext<'extract>,
123 frame_packet: Box<dyn RenderFeatureFramePacket>,
124 ) -> Arc<dyn RenderFeatureExtractJob<'extract> + 'extract> {
125 let text_material = extract_context
126 .render_resources
127 .fetch::<TextStaticResources>()
128 .text_material
129 .clone();
130
131 TextExtractJob::new(extract_context, frame_packet.into_concrete(), text_material)
132 }
133
134 fn new_submit_packet(
135 &self,
136 frame_packet: &Box<dyn RenderFeatureFramePacket>,
137 ) -> Box<dyn RenderFeatureSubmitPacket> {
138 let frame_packet: &TextFramePacket = frame_packet.as_ref().as_concrete();
139 let num_submit_nodes = frame_packet.per_frame_data().get().text_draw_commands.len();
140
141 let mut view_submit_packets = Vec::with_capacity(frame_packet.view_packets().len());
142 for view_packet in frame_packet.view_packets() {
143 let view_submit_packet = ViewSubmitPacket::from_view_packet::<UiRenderPhase>(
144 view_packet,
145 Some(num_submit_nodes),
146 );
147 view_submit_packets.push(view_submit_packet);
148 }
149
150 Box::new(TextSubmitPacket::new(
151 self.feature_index(),
152 frame_packet.render_object_instances().len(),
153 view_submit_packets,
154 ))
155 }
156
157 fn new_prepare_job<'prepare>(
158 &self,
159 prepare_context: &RenderJobPrepareContext<'prepare>,
160 frame_packet: Box<dyn RenderFeatureFramePacket>,
161 submit_packet: Box<dyn RenderFeatureSubmitPacket>,
162 ) -> Arc<dyn RenderFeaturePrepareJob<'prepare> + 'prepare> {
163 TextPrepareJob::new(
164 prepare_context,
165 frame_packet.into_concrete(),
166 submit_packet.into_concrete(),
167 )
168 }
169
170 fn new_write_job<'write>(
171 &self,
172 write_context: &RenderJobWriteContext<'write>,
173 frame_packet: Box<dyn RenderFeatureFramePacket>,
174 submit_packet: Box<dyn RenderFeatureSubmitPacket>,
175 ) -> Arc<dyn RenderFeatureWriteJob<'write> + 'write> {
176 TextWriteJob::new(
177 write_context,
178 frame_packet.into_concrete(),
179 submit_packet.into_concrete(),
180 )
181 }
182}