three_d_text_builder/geometry/
mesh.rs

1// External Dependencies ------------------------------------------------------
2// ----------------------------------------------------------------------------
3use three_d::{
4    AxisAlignedBoundingBox, Camera, Context,
5    Geometry, Material,
6    ColorTexture, DepthTexture,
7    FragmentAttributes, Effect, Light,
8    Program, RenderStates,
9    Vec2, Vec3, Vec4, Mat4, SquareMatrix, ElementBuffer, VertexBuffer,
10    renderer::{render_with_material, render_with_effect}
11};
12
13
14// Internal Dependencies ------------------------------------------------------
15// ----------------------------------------------------------------------------
16use crate::geometry::material::TextMaterial;
17
18
19// Structs --------------------------------------------------------------------
20// ----------------------------------------------------------------------------
21pub(crate) struct TextMeshData {
22    pub(crate) material: TextMaterial,
23    pub(crate) indices: Vec<u32>,
24    pub(crate) positions: Vec<Vec3>,
25    pub(crate) colors: Vec<Vec4>,
26    pub(crate) quad_uvs: Vec<Vec2>,
27    pub(crate) glyph_uvs: Vec<Vec2>
28}
29
30
31///
32/// A simple mesh geometry rendering mulitple rasterized font glyphs.
33///
34pub struct TextMesh {
35    aabb: AxisAlignedBoundingBox,
36    context: Context,
37
38    indices: ElementBuffer,
39    positions: VertexBuffer,
40    colors: VertexBuffer,
41    quad_uvs: VertexBuffer,
42    glyph_uvs: VertexBuffer,
43}
44
45impl TextMesh {
46    pub(crate) fn new(context: &Context, data: &TextMeshData) -> Self {
47        let mut aabb = AxisAlignedBoundingBox::EMPTY;
48        aabb.expand(&data.positions);
49
50        Self {
51            aabb,
52            context: context.clone(),
53            indices: ElementBuffer::new_with_data(context, &data.indices),
54            positions: VertexBuffer::new_with_data(context, &data.positions),
55            colors: VertexBuffer::new_with_data(context, &data.colors),
56            quad_uvs: VertexBuffer::new_with_data(context, &data.quad_uvs),
57            glyph_uvs: VertexBuffer::new_with_data(context, &data.glyph_uvs)
58        }
59    }
60}
61
62impl Geometry for TextMesh {
63    fn aabb(&self) -> AxisAlignedBoundingBox {
64        self.aabb
65    }
66
67    fn id(&self, _required_attributes: FragmentAttributes) -> u16 {
68        0b1u16 << 12 | 1u16 << 4
69    }
70
71    fn draw(
72        &self,
73        camera: &Camera,
74        program: &Program,
75        render_states: RenderStates,
76        _: FragmentAttributes,
77    ) {
78        if self.positions.count() > 0 {
79            program.use_vertex_attribute("position", &self.positions);
80            program.use_vertex_attribute("color", &self.colors);
81            program.use_vertex_attribute("quad_coordinates", &self.quad_uvs);
82            program.use_vertex_attribute("glyph_coordinates", &self.glyph_uvs);
83            program.use_uniform("viewProjection", camera.projection() * camera.view());
84            program.use_uniform("modelMatrix", Mat4::identity());
85            program.draw_elements(render_states, camera.viewport(), &self.indices);
86        }
87    }
88
89    fn vertex_shader_source(&self, _: FragmentAttributes) -> String {
90        include_str!("mesh.vert").to_string()
91    }
92
93    fn render_with_material(
94        &self,
95        material: &dyn Material,
96        camera: &Camera,
97        lights: &[&dyn Light],
98    ) {
99        render_with_material(&self.context, camera, &self, material, lights);
100    }
101
102    fn render_with_effect(
103        &self,
104        material: &dyn Effect,
105        camera: &Camera,
106        lights: &[&dyn Light],
107        color_texture: Option<ColorTexture>,
108        depth_texture: Option<DepthTexture>,
109    ) {
110        render_with_effect(
111            &self.context,
112            camera,
113            self,
114            material,
115            lights,
116            color_texture,
117            depth_texture,
118        );
119    }
120}
121