makepad_draw/shader/
draw_quad.rs

1use {
2    crate::{
3        makepad_platform::*,
4        draw_list_2d::ManyInstances,
5        geometry::GeometryQuad2D,
6        cx_2d::Cx2d,
7        turtle::{Walk, Layout}
8    },
9};
10
11live_design!{
12    
13    DrawQuad = {{DrawQuad}} {
14        varying pos: vec2
15        
16        fn clip_and_transform_vertex(self, rect_pos:vec2, rect_size:vec2) -> vec4 {
17            let clipped: vec2 = clamp(
18                self.geom_pos * rect_size + rect_pos,
19                self.draw_clip.xy,
20                self.draw_clip.zw
21            )
22            //clipped = self.geom_pos * rect_size + rect_pos;
23            self.pos = (clipped - rect_pos) / rect_size
24            // only pass the clipped position forward
25            return self.camera_projection * (self.camera_view * (self.view_transform * vec4(
26                clipped.x,
27                clipped.y,
28                self.draw_depth + self.draw_zbias,
29                1.
30            )))
31        }
32        
33        fn transform_vertex(self, rect_pos:vec2, rect_size:vec2) -> vec4 {
34            let clipped: vec2 = self.geom_pos * rect_size + rect_pos;
35            
36            self.pos = (clipped - rect_pos) / rect_size
37            // only pass the clipped position forward
38            return self.camera_projection * (self.camera_view * (self.view_transform * vec4(
39                clipped.x,
40                clipped.y,
41                self.draw_depth + self.draw_zbias,
42                1.
43            )))
44        }
45        
46        fn vertex(self) -> vec4 {
47            return self.clip_and_transform_vertex(self.rect_pos, self.rect_size)
48        }
49        
50        fn pixel(self) -> vec4 {
51            return #f0f
52        }
53    }
54}
55
56#[derive(Live)]
57#[repr(C)]
58pub struct DrawQuad {
59    #[rust] pub many_instances: Option<ManyInstances>,
60    #[live] pub geometry: GeometryQuad2D,
61    #[deref] pub draw_vars: DrawVars,
62    #[calc] pub rect_pos: Vec2,
63    #[calc] pub rect_size: Vec2,
64    #[calc] pub draw_clip: Vec4,
65    #[live(1.0)] pub draw_depth: f32,
66}
67
68impl LiveHook for DrawQuad{
69    fn before_apply(&mut self, cx: &mut Cx, apply_from: ApplyFrom, index: usize, nodes: &[LiveNode]){
70        self.draw_vars.before_apply_init_shader(cx, apply_from, index, nodes, &self.geometry);
71    }
72    fn after_apply(&mut self, cx: &mut Cx, apply_from: ApplyFrom, index: usize, nodes: &[LiveNode]) {
73        self.draw_vars.after_apply_update_self(cx, apply_from, index, nodes, &self.geometry);
74    }
75}
76
77impl DrawQuad {
78    pub fn begin(&mut self, cx: &mut Cx2d, walk: Walk, layout: Layout) {
79        cx.begin_turtle(walk, layout);
80        if self.draw_vars.draw_shader.is_some() {
81            let new_area = cx.add_aligned_instance(&self.draw_vars);
82            self.draw_vars.area = cx.update_area_refs(self.draw_vars.area, new_area);
83        }
84    }
85    
86    pub fn end(&mut self, cx: &mut Cx2d) {
87        let rect = cx.end_turtle();
88        self.draw_vars.area.set_rect(cx, &rect);
89    }
90    
91    pub fn draw_walk(&mut self, cx: &mut Cx2d, walk: Walk) -> Rect {
92        let rect = cx.walk_turtle(walk);
93        self.rect_pos = rect.pos.into();
94        self.rect_size = rect.size.into();
95        self.draw(cx);
96        rect
97    }
98    
99    pub fn draw(&mut self, cx: &mut Cx2d) {
100        if let Some(mi) = &mut self.many_instances {
101            mi.instances.extend_from_slice(self.draw_vars.as_slice());
102        }
103        else if self.draw_vars.can_instance() {
104            let new_area = cx.add_aligned_instance(&self.draw_vars);
105            self.draw_vars.area = cx.update_area_refs(self.draw_vars.area, new_area);
106        }
107    }
108    
109    pub fn update_abs(&mut self, cx: &mut Cx, rect: Rect) {
110        self.rect_pos = rect.pos.into();
111        self.rect_size = rect.size.into();
112        self.draw_vars.update_rect(cx, rect);
113    }
114    
115    pub fn draw_abs(&mut self, cx: &mut Cx2d, rect: Rect) {
116        self.rect_pos = rect.pos.into();
117        self.rect_size = rect.size.into();
118        self.draw(cx);
119    }
120    
121    pub fn draw_rel(&mut self, cx: &mut Cx2d, rect: Rect) {
122        let rect = rect.translate(cx.turtle().origin());
123        self.rect_pos = rect.pos.into();
124        self.rect_size = rect.size.into();
125        self.draw(cx);
126    }
127    
128    pub fn new_draw_call(&self, cx: &mut Cx2d) {
129        cx.new_draw_call(&self.draw_vars);
130    }
131    
132    pub fn append_to_draw_call(&self, cx: &mut Cx2d) {
133        cx.new_draw_call(&self.draw_vars);
134    }
135    
136    pub fn begin_many_instances(&mut self, cx: &mut Cx2d) {
137        let mi = cx.begin_many_aligned_instances(&self.draw_vars);
138        self.many_instances = mi;
139    }
140    
141    pub fn end_many_instances(&mut self, cx: &mut Cx2d) {
142        if let Some(mi) = self.many_instances.take() {
143            let new_area = cx.end_many_instances(mi);
144            self.draw_vars.area = cx.update_area_refs(self.draw_vars.area, new_area);
145        }
146    }
147}