1use crate::*;
2use std::borrow::Cow;
3
4#[derive(Debug)]
6pub struct SpriteRenderer {
7 renderer: MeshRenderer,
8 rect: Mesh,
9 white: Texture,
10 matrix: glam::Mat4,
11}
12
13impl SpriteRenderer {
14 pub fn new(cx: &Context, pipeline: &MeshRenderPipeline) -> Self {
18 let renderer = MeshRenderer::new(cx, pipeline);
19
20 let rect = Mesh::new(
21 &cx,
22 &[
23 Vertex {
24 pos: [0., 0.],
25 uv: [0., 0.],
26 },
27 Vertex {
28 pos: [1., 0.],
29 uv: [1., 0.],
30 },
31 Vertex {
32 pos: [0., 1.],
33 uv: [0., 1.],
34 },
35 Vertex {
36 pos: [1., 1.],
37 uv: [1., 1.],
38 },
39 ],
40 &[0, 2, 1, 2, 3, 1],
41 );
42
43 let white = ImageTexture {
44 format: wgpu::TextureFormat::Rgba8UnormSrgb,
45 pixels: Cow::Borrowed(&[255, 255, 255, 255]),
46 width: 1,
47 height: 1,
48 }
49 .create(&cx);
50
51 SpriteRenderer {
52 renderer,
53 rect,
54 white,
55 matrix: glam::Mat4::IDENTITY,
56 }
57 }
58
59 pub fn free(&mut self) {
63 self.renderer.free();
64 }
65
66 pub fn bind_sampler<'a>(
68 &mut self,
69 cx: &Context,
70 pass: &'a mut wgpu::RenderPass,
71 sampler: &Sampler,
72 ) {
73 self.renderer.bind_sampler(cx, pass, sampler);
74 }
75
76 pub fn set_matrix(&mut self, matrix: glam::Mat4) {
78 self.matrix = matrix;
79 }
80
81 pub fn draw<'a>(
85 &mut self,
86 cx: &Context,
87 pass: &mut ArenaRenderPass,
88 content: impl Into<SpriteContent<'a>>,
89 rect: Rect,
90 rotation: f32,
91 ) {
92 let (texture, src_rect, color) = match content.into() {
93 SpriteContent::Textured { texture, src_rect } => (texture, src_rect, Color::WHITE),
94 SpriteContent::Color(color) => (&self.white, Rect::ONE, color),
95 };
96
97 self.renderer.draw(
98 cx,
99 pass,
100 MeshDraw {
101 mesh: &self.rect,
102 texture,
103 color,
104 src_rect,
105 transform: glam::Mat4::from_scale_rotation_translation(
106 glam::vec3(rect.size.x, rect.size.y, 1.),
107 glam::Quat::from_rotation_z(rotation),
108 glam::vec3(rect.origin.x, rect.origin.y, 0.),
109 ),
110 },
111 );
112 }
113}
114
115impl Slot3MeshRenderer for SpriteRenderer {
116 #[inline]
117 fn bind(&mut self, uniform: u32, texture: u32, sampler: u32) {
118 self.renderer.bind(uniform, texture, sampler);
119 }
120}
121
122pub enum SpriteContent<'a> {
124 Textured {
126 texture: &'a Texture,
128 src_rect: Rect,
131 },
132 Color(Color),
134}
135
136impl<'a> From<&'a Texture> for SpriteContent<'a> {
137 fn from(texture: &'a Texture) -> Self {
138 SpriteContent::Textured {
139 texture,
140 src_rect: Rect::ONE,
141 }
142 }
143}
144
145impl<'a> From<(&'a Texture, Rect)> for SpriteContent<'a> {
146 fn from((texture, src_rect): (&'a Texture, Rect)) -> Self {
147 SpriteContent::Textured { texture, src_rect }
148 }
149}
150
151impl<'a> From<Color> for SpriteContent<'a> {
152 fn from(color: Color) -> Self {
153 SpriteContent::Color(color)
154 }
155}