makepad_render/
blit.rs

1use crate::cx::*;
2
3#[derive(Clone)]
4pub struct Blit {
5    pub shader: Shader,
6    pub min_x: f32,
7    pub min_y: f32,
8    pub max_x: f32,
9    pub max_y: f32,
10    pub alpha: f32,
11    pub do_scroll: bool
12}
13
14impl Blit {
15    pub fn style(cx: &mut Cx) -> Self {
16        Self {
17            alpha: 1.0,
18            min_x:0.0,
19            min_y:0.0,
20            max_x:1.0,
21            max_y:1.0,
22            shader: cx.add_shader(Self::def_blit_shader(), "Blit"),
23            do_scroll:false,
24        }
25    }
26    
27    pub fn instance_x()->InstanceFloat{uid!()}
28    pub fn instance_y()->InstanceFloat{uid!()}
29    pub fn instance_w()->InstanceFloat{uid!()}
30    pub fn instance_h()->InstanceFloat{uid!()}
31    pub fn instance_min_x()->InstanceFloat{uid!()}
32    pub fn instance_min_y()->InstanceFloat{uid!()}
33    pub fn instance_max_x()->InstanceFloat{uid!()}
34    pub fn instance_max_y()->InstanceFloat{uid!()}
35    pub fn instance_z()->InstanceFloat{uid!()}
36    pub fn instance_color()->InstanceColor{uid!()}
37    pub fn uniform_alpha()->UniformFloat{uid!()}
38    
39    pub fn def_blit_shader() -> ShaderGen {
40        // lets add the draw shader lib
41        let mut sb = ShaderGen::new();
42        
43        sb.geometry_vertices = vec![0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0];
44        sb.geometry_indices = vec![0, 1, 2, 2, 3, 0];
45        
46        sb.compose(shader_ast!({
47            
48            let geom: vec2<Geometry>;
49            let x: Self::instance_x();
50            let y: Self::instance_y();
51            let w: Self::instance_w();
52            let h: Self::instance_h();
53            let min_x: Self::instance_min_x();
54            let min_y: Self::instance_min_y();
55            let max_x: Self::instance_max_x();
56            let max_y: Self::instance_max_y();
57            let tc: vec2<Varying>;
58            let alpha: Self::uniform_alpha();
59            let texturez:texture2d<Texture>;
60            let v_pixel: vec2<Varying>;
61            //let dpi_dilate: float<Uniform>;
62            
63            fn vertex() -> vec4 {
64                // return vec4(geom.x-0.5, geom.y, 0., 1.);
65                let shift: vec2 = -draw_scroll.xy;
66                let clipped: vec2 = clamp(
67                    geom * vec2(w, h) + vec2(x, y) + shift,
68                    draw_clip.xy,
69                    draw_clip.zw
70                ); 
71                let pos = (clipped - shift - vec2(x, y)) / vec2(w, h);
72                tc = mix(vec2(min_x,min_y), vec2(max_x,max_y), pos);
73                v_pixel = clipped;
74                // only pass the clipped position forward
75                return camera_projection * vec4(clipped.x, clipped.y, 0., 1.);
76            }
77            
78            fn pixel() -> vec4 {
79                return vec4(sample2d(texturez, tc.xy).rgb, alpha);
80            }
81            
82        }))
83    }
84    
85    
86    pub fn begin_blit(&mut self, cx: &mut Cx, texture:&Texture, layout: Layout) -> InstanceArea {
87        let inst = self.draw_blit(cx, texture, Rect::default());
88        let area = inst.clone().into();
89        cx.begin_turtle(layout, area);
90        inst
91    }
92    
93    pub fn end_blit(&mut self, cx: &mut Cx, inst: &InstanceArea) -> Area {
94        let area = inst.clone().into();
95        let rect = cx.end_turtle(area);
96        area.set_rect(cx, &rect);
97        area
98    }
99    
100    pub fn draw_blit_walk(&mut self, cx: &mut Cx, texture:&Texture, walk:Walk) -> InstanceArea {
101        let geom = cx.walk_turtle(walk);
102        let inst = self.draw_blit_abs(cx, texture, geom);
103        cx.align_instance(inst);
104        inst
105    }
106    
107    pub fn draw_blit(&mut self, cx: &mut Cx, texture:&Texture, rect: Rect) -> InstanceArea {
108        let pos = cx.get_turtle_origin();
109        let inst = self.draw_blit_abs(cx, texture, Rect {x: rect.x + pos.x, y: rect.y + pos.y, w: rect.w, h: rect.h});
110        cx.align_instance(inst);
111        inst
112    }
113    
114    pub fn draw_blit_abs(&mut self, cx: &mut Cx, texture:&Texture, rect: Rect) -> InstanceArea {
115        let inst = cx.new_instance_draw_call(&self.shader, 1);
116        if inst.need_uniforms_now(cx) {
117            inst.push_uniform_float(cx, if self.do_scroll {1.0}else {0.0});
118            inst.push_uniform_float(cx, self.alpha);
119            inst.push_uniform_texture_2d(cx, texture);
120        }
121        //println!("{:?} {}", area, cx.current_draw_list_id);
122        let data = [
123            /*x,y,w,h*/rect.x,
124            rect.y,
125            rect.w,
126            rect.h,
127            self.min_x,
128            self.min_y,
129            self.max_x,
130            self.max_y
131        ];
132        inst.push_slice(cx, &data);
133        inst
134    }
135}