makepad_draw/shader/
draw_quad.rs1use {
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 self.pos = (clipped - rect_pos) / rect_size
24 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 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}