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