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 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 fn scroll() -> vec2{
53 return draw_scroll.xy
54 }
55
56 fn vertex() -> vec4 {
57 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 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 let data = [
122 rect.x,
123 rect.y,
124 rect.w,
125 rect.h,
126 self.z,
127 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}