1use std::collections::BTreeMap;
4
5use crate::{brush::Brush, canvas::ShaderData, geo::Rect, tex::Texture};
6
7pub struct GraphicsContext<'a> {
9 pub(crate) render_pass: wgpu::RenderPass<'a>,
10 pub(crate) shader_data: ShaderData,
11 pub(crate) viewport: Rect,
12 pub(crate) bind_group_table: &'a BTreeMap<u64, wgpu::BindGroup>,
13}
14
15impl<'a> GraphicsContext<'a> {
16 pub fn set_brush(&mut self, brush: &Brush) {
18 self.shader_data.brush = brush.to_shader_data();
19 }
20
21 pub fn set_texture(&mut self, texture: &Texture, rect: &Rect) {
23 self.shader_data.tex_pos[0] = rect.pos.x as f32 / texture.size.width as f32;
24 self.shader_data.tex_pos[1] = rect.pos.y as f32 / texture.size.height as f32;
25
26 self.shader_data.tex_size[0] = rect.size.width as f32 / texture.size.width as f32;
27 self.shader_data.tex_size[1] = rect.size.height as f32 / texture.size.height as f32;
28
29 self.render_pass.set_bind_group(
30 0,
31 self.bind_group_table
32 .get(&texture.bind_group_index)
33 .unwrap(),
34 &[],
35 );
36 }
37
38 pub fn fill_rect(&mut self, rect: &Rect) {
40 let fwidth = self.viewport.size.width as f32;
41 let fheight = self.viewport.size.height as f32;
42
43 let converted_y = self.viewport.size.height as i32 - rect.pos.y - rect.size.height as i32;
44
45 self.shader_data.pos[0] = (2.0 * rect.pos.x as f32 / fwidth) - 1.0;
46 self.shader_data.pos[1] = (2.0 * converted_y as f32 / fheight) - 1.0;
47
48 self.shader_data.size[0] = 2.0 * rect.size.width as f32 / fwidth;
49 self.shader_data.size[1] = 2.0 * rect.size.height as f32 / fheight;
50
51 self.render_pass.set_push_constants(
52 wgpu::ShaderStages::VERTEX,
53 0,
54 self.shader_data.as_bytes(),
55 );
56 self.render_pass.draw(0..6, 0..1);
57 }
58}