three_d_text_builder/geometry/
material.rs

1// STD Dependencies -----------------------------------------------------------
2// ----------------------------------------------------------------------------
3use std::sync::Arc;
4
5
6// External Dependencies ------------------------------------------------------
7// ----------------------------------------------------------------------------
8use three_d::{Blend, Camera, Context, Program, RenderStates, Texture2D, WriteMask, ColorMapping, ToneMapping, Srgba, DepthTest};
9use three_d::renderer::{CpuMaterial, FragmentAttributes, Light, Material, MaterialType, Texture2DRef};
10
11
12///
13/// A single channel material storing rasterized font glyphs.
14///
15#[derive(Clone)]
16pub struct TextMaterial {
17    pub(crate) edge_color: Srgba,
18    pub(crate) texture: Texture2DRef,
19    pub(crate) render_states: RenderStates,
20}
21
22impl TextMaterial {
23    pub(crate) fn new(context: &Context, cpu_material: &CpuMaterial) -> Option<Self> {
24        let cpu_texture = cpu_material.albedo_texture.as_ref()?;
25        Some(Self {
26            edge_color: Srgba::new(0, 0, 0, 0),
27            texture: Arc::new(Texture2D::new(context, cpu_texture)).into(),
28            render_states: RenderStates {
29                write_mask: WriteMask::COLOR,
30                blend: Blend::TRANSPARENCY,
31                depth_test: DepthTest::LessOrEqual,
32                ..Default::default()
33            },
34        })
35    }
36
37    pub(crate) fn set_edge_color(&mut self, color: Option<Srgba>) {
38        self.edge_color = color.unwrap_or(Srgba::new(0, 0, 0, 0));
39    }
40
41    /// Returns the GPU texture storing the currently rasterized font glyphs.
42    pub fn texture(&self) -> &Texture2DRef {
43        &self.texture
44    }
45}
46
47impl Material for TextMaterial {
48    fn id(&self) -> u16 {
49        0b1u16 << 12 | 1u16 << 4
50    }
51
52    fn fragment_shader_source(&self, _lights: &[&dyn Light]) -> String {
53        let mut source = String::new();
54        source.push_str(ToneMapping::fragment_shader_source());
55        source.push_str(ColorMapping::fragment_shader_source());
56        source.push_str(include_str!("material.frag"));
57        source
58    }
59
60    fn fragment_attributes(&self) -> FragmentAttributes {
61        FragmentAttributes {
62            color: true,
63            uv: true,
64            normal: true,
65            ..FragmentAttributes::NONE
66        }
67    }
68
69    fn use_uniforms(&self, program: &Program, camera: &Camera, _lights: &[&dyn Light]) {
70        camera.tone_mapping.use_uniforms(program);
71        camera.color_mapping.use_uniforms(program);
72        program.use_texture("tex", &self.texture);
73        program.use_uniform("edgeColor", self.edge_color.to_linear_srgb());
74    }
75
76    fn render_states(&self) -> RenderStates {
77        self.render_states
78    }
79
80    fn material_type(&self) -> MaterialType {
81        MaterialType::Transparent
82    }
83}
84