1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use crate::{BufferData, BufferLayout};
use cosmic_text::Color;
use lyon::{math::Point as LPoint, tessellation as tess};
use std::iter;

#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub struct Mesh2DVertex {
    pub position: [f32; 3],
    pub color: u32,
    pub camera: u32,
}

impl Default for Mesh2DVertex {
    fn default() -> Self {
        Self {
            position: [0.0; 3],
            color: 0,
            camera: 0,
        }
    }
}

impl BufferLayout for Mesh2DVertex {
    fn attributes() -> Vec<wgpu::VertexAttribute> {
        wgpu::vertex_attr_array![0 => Float32x3, 1 => Uint32, 2 => Uint32]
            .to_vec()
    }

    //default set as large enough to contain 1_000 vertices.
    fn default_buffer() -> BufferData {
        Self::with_capacity(1_000, 6_000)
    }

    fn with_capacity(
        vertex_capacity: usize,
        index_capacity: usize,
    ) -> BufferData {
        let vbo_arr: Vec<Mesh2DVertex> = iter::repeat(Mesh2DVertex::default())
            .take(vertex_capacity)
            .collect();

        let mut indices: Vec<u32> = Vec::with_capacity(index_capacity * 6);
        (0..index_capacity as u32).for_each(|_| {
            indices.extend_from_slice(&[0, 0, 0, 0, 0, 0]);
        });

        BufferData {
            vertexs: bytemuck::cast_slice(&vbo_arr).to_vec(),
            indexs: bytemuck::cast_slice(&indices).to_vec(),
        }
    }

    fn stride() -> usize {
        std::mem::size_of::<[f32; 5]>()
    }
}

#[derive(Copy, Clone, PartialEq, Debug)]
pub struct VertexBuilder {
    pub z: f32,
    pub color: Color,
    pub camera: bool,
}

impl VertexBuilder {
    pub fn new_vertex(self, position: LPoint) -> Mesh2DVertex {
        Mesh2DVertex {
            position: [position.x, position.y, self.z],
            color: self.color.0,
            camera: u32::from(self.camera),
        }
    }
}

impl tess::StrokeVertexConstructor<Mesh2DVertex> for VertexBuilder {
    fn new_vertex(&mut self, vertex: tess::StrokeVertex) -> Mesh2DVertex {
        let position = vertex.position();
        Mesh2DVertex {
            position: [position.x, position.y, self.z],
            color: self.color.0,
            camera: u32::from(self.camera),
        }
    }
}

impl tess::FillVertexConstructor<Mesh2DVertex> for VertexBuilder {
    fn new_vertex(&mut self, vertex: tess::FillVertex) -> Mesh2DVertex {
        let position = vertex.position();
        Mesh2DVertex {
            position: [position.x, position.y, self.z],
            color: self.color.0,
            camera: u32::from(self.camera),
        }
    }
}