three_d_text_builder/geometry/
material.rs1use std::sync::Arc;
4
5
6use 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#[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 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