1use super::*;
2
3pub struct Polygon {
4 pub transform: mat3<f32>,
5 pub draw_mode: ugli::DrawMode,
6 pub vertices: Vec<ColoredVertex>,
7}
8
9impl Polygon {
10 pub fn new(vertices: Vec<vec2<f32>>, color: Rgba<f32>) -> Self {
11 Self::new_gradient(
12 vertices
13 .into_iter()
14 .map(|vertex| ColoredVertex {
15 a_pos: vertex,
16 a_color: color,
17 })
18 .collect(),
19 )
20 }
21 pub fn new_gradient(vertices: Vec<ColoredVertex>) -> Self {
22 let (transform, vertices) = Self::normalize(vertices);
23 Self {
24 transform,
25 vertices,
26 draw_mode: ugli::DrawMode::TriangleFan,
27 }
28 }
29 pub fn strip(vertices: Vec<vec2<f32>>, color: Rgba<f32>) -> Self {
30 Self::strip_gradient(
31 vertices
32 .into_iter()
33 .map(|vertex| ColoredVertex {
34 a_pos: vertex,
35 a_color: color,
36 })
37 .collect(),
38 )
39 }
40 pub fn strip_gradient(vertices: Vec<ColoredVertex>) -> Self {
41 let (transform, vertices) = Self::normalize(vertices);
42 Self {
43 transform,
44 vertices,
45 draw_mode: ugli::DrawMode::TriangleStrip,
46 }
47 }
48
49 pub(super) fn normalize(mut vertices: Vec<ColoredVertex>) -> (mat3<f32>, Vec<ColoredVertex>) {
50 let aabb = Aabb2::points_bounding_box(vertices.iter().map(|vertex| vertex.a_pos)).unwrap();
51 let transform = mat3::translate(aabb.center()) * mat3::scale(aabb.size() / 2.0);
52 let inverse = transform.inverse();
53 for vertex in &mut vertices {
54 vertex.a_pos = (inverse * vertex.a_pos.extend(1.0)).xy();
55 }
56 (transform, vertices)
57 }
58}
59
60impl Draw2d for Polygon {
61 fn draw2d_transformed(
62 &self,
63 helper: &Helper,
64 framebuffer: &mut ugli::Framebuffer,
65 camera: &dyn AbstractCamera2d,
66 transform: mat3<f32>,
67 ) {
68 let framebuffer_size = framebuffer.size();
69 ugli::draw(
70 framebuffer,
71 &helper.color_program,
72 self.draw_mode,
73 &ugli::VertexBuffer::new_dynamic(helper.ugli(), self.vertices.clone()),
74 (
75 ugli::uniforms! {
76 u_color: Rgba::WHITE,
77 u_framebuffer_size: framebuffer_size,
78 u_model_matrix: transform * self.transform,
79 },
80 camera.uniforms(framebuffer_size.map(|x| x as f32)),
81 ),
82 ugli::DrawParameters {
83 blend_mode: Some(ugli::BlendMode::straight_alpha()),
84 ..Default::default()
85 },
86 );
87 }
88}
89
90impl Transform2d<f32> for Polygon {
91 fn bounding_quad(&self) -> batbox_lapp::Quad<f32> {
92 batbox_lapp::Quad {
93 transform: self.transform,
94 }
95 }
96 fn apply_transform(&mut self, transform: mat3<f32>) {
97 self.transform = transform * self.transform;
98 }
99}
100
101pub struct TexturedPolygon<T: std::borrow::Borrow<ugli::Texture>> {
102 transform: mat3<f32>,
103 texture: T,
104 draw_mode: ugli::DrawMode,
105 vertices: Vec<TexturedVertex>,
106}
107
108impl<T: std::borrow::Borrow<ugli::Texture>> TexturedPolygon<T> {
109 pub fn new(vertices: Vec<TexturedVertex>, texture: T) -> Self {
110 let (transform, vertices) = Self::normalize(vertices);
111 Self {
112 transform,
113 texture,
114 vertices,
115 draw_mode: ugli::DrawMode::TriangleFan,
116 }
117 }
118 pub fn with_mode(vertices: Vec<TexturedVertex>, texture: T, draw_mode: ugli::DrawMode) -> Self {
119 let (transform, vertices) = Self::normalize(vertices);
120 Self {
121 transform,
122 texture,
123 vertices,
124 draw_mode,
125 }
126 }
127 pub fn strip(vertices: Vec<TexturedVertex>, texture: T) -> Self {
128 let (transform, vertices) = Self::normalize(vertices);
129 Self {
130 transform,
131 texture,
132 vertices,
133 draw_mode: ugli::DrawMode::TriangleStrip,
134 }
135 }
136
137 pub(super) fn normalize(mut vertices: Vec<TexturedVertex>) -> (mat3<f32>, Vec<TexturedVertex>) {
138 let aabb = Aabb2::points_bounding_box(vertices.iter().map(|vertex| vertex.a_pos)).unwrap();
139 let transform = mat3::translate(aabb.center()) * mat3::scale(aabb.size() / 2.0);
140 let inverse = transform.inverse();
141 for vertex in &mut vertices {
142 vertex.a_pos = (inverse * vertex.a_pos.extend(1.0)).xy();
143 }
144 (transform, vertices)
145 }
146}
147
148impl<T: std::borrow::Borrow<ugli::Texture>> Draw2d for TexturedPolygon<T> {
149 fn draw2d_transformed(
150 &self,
151 helper: &Helper,
152 framebuffer: &mut ugli::Framebuffer,
153 camera: &dyn AbstractCamera2d,
154 transform: mat3<f32>,
155 ) {
156 let framebuffer_size = framebuffer.size();
157 ugli::draw(
158 framebuffer,
159 &helper.textured_program,
160 self.draw_mode,
161 &ugli::VertexBuffer::new_dynamic(helper.ugli(), self.vertices.clone()),
162 (
163 ugli::uniforms! {
164 u_color: Rgba::WHITE,
165 u_texture: self.texture.borrow(),
166 u_framebuffer_size: framebuffer_size,
167 u_model_matrix: transform * self.transform,
168 u_texture_matrix: mat3::identity(),
169 },
170 camera.uniforms(framebuffer_size.map(|x| x as f32)),
171 ),
172 ugli::DrawParameters {
173 blend_mode: Some(ugli::BlendMode::straight_alpha()),
174 ..Default::default()
175 },
176 );
177 }
178}
179
180impl<T: std::borrow::Borrow<ugli::Texture>> Transform2d<f32> for TexturedPolygon<T> {
181 fn bounding_quad(&self) -> batbox_lapp::Quad<f32> {
182 batbox_lapp::Quad {
183 transform: self.transform,
184 }
185 }
186 fn apply_transform(&mut self, transform: mat3<f32>) {
187 self.transform = transform * self.transform;
188 }
189}