makepad_render/
quad.rs

1use crate::cx::*;
2
3#[derive(Clone)]
4pub struct Quad {
5    pub shader: Shader,
6    pub z: f32,
7    pub color: Color
8}
9
10impl Quad {
11    pub fn proto_with_shader(cx: &mut Cx, shader: ShaderGen, name: &str) -> Self {
12        Self {
13            shader: cx.add_shader(shader, name),
14            ..Self::new(cx)
15        }
16    }
17    
18    pub fn new(cx: &mut Cx) -> Self {
19        Self {
20            shader: cx.add_shader(Self::def_quad_shader(), "Quad"),
21            z: 0.0,
22            color: color("green")
23        }
24    }
25    
26    pub fn instance_x() -> InstanceFloat {uid!()}
27    pub fn instance_y() -> InstanceFloat {uid!()}
28    pub fn instance_w() -> InstanceFloat {uid!()}
29    pub fn instance_h() -> InstanceFloat {uid!()}
30    pub fn instance_z() -> InstanceFloat {uid!()}
31    pub fn instance_color() -> InstanceColor {uid!()}
32    
33    pub fn def_quad_shader() -> ShaderGen {
34        // lets add the draw shader lib
35        let mut sg = ShaderGen::new();
36        sg.geometry_vertices = vec![0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0];
37        sg.geometry_indices = vec![0, 1, 2, 2, 3, 0];
38        
39        sg.compose(shader_ast!({
40            
41            let geom: vec2<Geometry>;
42            let pos: vec2<Varying>;
43            
44            let x: Self::instance_x();
45            let y: Self::instance_y();
46            let w: Self::instance_w();
47            let h: Self::instance_h();
48            let z: Self::instance_z();
49            let color: Self::instance_color();
50            
51            //let dpi_dilate: float<Uniform>;
52            fn scroll() -> vec2{
53                return draw_scroll.xy
54            }
55            
56            fn vertex() -> vec4 {
57                // return vec4(geom.x-0.5, geom.y, 0., 1.);
58                let scr = scroll();
59                let clipped: vec2 = clamp(
60                    geom * vec2(w, h) + vec2(x, y) - scr,
61                    draw_clip.xy,
62                    draw_clip.zw
63                );
64                pos = (clipped + scr - vec2(x, y)) / vec2(w, h);
65                // only pass the clipped position forward
66                return camera_projection * (camera_view * (view_transform * vec4(clipped.x, clipped.y, z + draw_zbias, 1.)));
67            }
68            
69            fn pixel() -> vec4 {
70                return vec4(color.rgb * color.a, color.a);
71            }
72            
73        }))
74    }
75    
76    pub fn begin_quad(&mut self, cx: &mut Cx, layout: Layout) -> InstanceArea {
77        let inst = self.draw_quad_rel(cx, Rect::default());
78        let area = inst.clone().into();
79        cx.begin_turtle(layout, area);
80        inst
81    }
82
83    pub fn end_quad(&mut self, cx: &mut Cx, inst: &InstanceArea) -> Area {
84        let area = inst.clone().into();
85        let rect = cx.end_turtle(area);
86        area.set_rect(cx, &rect);
87        area
88    }
89    
90    pub fn begin_quad_fill(&mut self, cx: &mut Cx) -> InstanceArea {
91        let inst = self.draw_quad_rel(cx, Rect::default());
92        inst
93    }
94
95    pub fn end_quad_fill(&mut self, cx: &mut Cx, inst: &InstanceArea) -> Area {
96        let area:Area = inst.clone().into();
97        let pos = cx.get_turtle_origin();
98        area.set_rect(cx, &Rect {x: pos.x, y: pos.y, w: cx.get_width_total(), h: cx.get_height_total()});
99        area
100    }
101    
102    pub fn draw_quad(&mut self, cx: &mut Cx, walk: Walk) -> InstanceArea {
103        let geom = cx.walk_turtle(walk);
104        let inst = self.draw_quad_abs(cx, geom);
105        cx.align_instance(inst);
106        inst
107    }
108    
109    pub fn draw_quad_rel(&mut self, cx: &mut Cx, rect: Rect) -> InstanceArea {
110        let pos = cx.get_turtle_origin();
111        let inst = self.draw_quad_abs(cx, Rect {x: rect.x + pos.x, y: rect.y + pos.y, w: rect.w, h: rect.h});
112        cx.align_instance(inst);
113        inst
114    }
115    
116    pub fn draw_quad_abs(&mut self, cx: &mut Cx, rect: Rect) -> InstanceArea {
117        let inst = cx.new_instance(&self.shader, 1);
118        if inst.need_uniforms_now(cx) {
119        }
120        //println!("{:?} {}", area, cx.current_draw_list_id);
121        let data = [
122            /*x,y,w,h*/rect.x,
123            rect.y,
124            rect.w,
125            rect.h,
126            self.z,
127            /*color*/self.color.r,
128            self.color.g,
129            self.color.b,
130            self.color.a
131        ];
132        inst.push_slice(cx, &data);
133        inst
134    }
135}