makepad_render/
pass.rs

1use crate::cx::*;
2
3#[derive(Default, Clone)]
4pub struct Pass {
5    pub pass_id: Option<usize>
6}
7
8
9impl Pass {
10    pub fn begin_pass(&mut self, cx: &mut Cx) {
11        
12        if self.pass_id.is_none() { // we need to allocate a CxPass
13            self.pass_id = Some(if cx.passes_free.len() != 0 {
14                cx.passes_free.pop().unwrap()
15            } else {
16                cx.passes.push(CxPass::default());
17                cx.passes.len() - 1
18            });
19        }
20        let pass_id = self.pass_id.unwrap();
21        
22        if let Some(window_id) = cx.window_stack.last() {
23            if cx.windows[*window_id].main_pass_id.is_none() { // we are the main pass of a window
24                let cxpass = &mut cx.passes[pass_id];
25                cx.windows[*window_id].main_pass_id = Some(pass_id);
26                cxpass.dep_of = CxPassDepOf::Window(*window_id);
27                cxpass.pass_size = cx.windows[*window_id].get_inner_size();
28                cx.current_dpi_factor = cx.get_delegated_dpi_factor(pass_id);
29            }
30            else if let Some(dep_of_pass_id) = cx.pass_stack.last() { 
31                let dep_of_pass_id = *dep_of_pass_id;
32                cx.passes[pass_id].dep_of = CxPassDepOf::Pass(dep_of_pass_id);
33                cx.passes[pass_id].pass_size = cx.passes[dep_of_pass_id].pass_size;
34                cx.current_dpi_factor = cx.get_delegated_dpi_factor(dep_of_pass_id);
35            }
36            else {
37                cx.passes[pass_id].dep_of = CxPassDepOf::None;
38                cx.passes[pass_id].override_dpi_factor = Some(1.0);
39                cx.current_dpi_factor = 1.0;
40            }
41        }
42        else {
43            cx.passes[pass_id].dep_of = CxPassDepOf::None;
44            cx.passes[pass_id].override_dpi_factor = Some(1.0);
45            cx.current_dpi_factor = 1.0;
46        }
47        
48        let cxpass = &mut cx.passes[pass_id];
49        cxpass.main_view_id = None;
50        cxpass.color_textures.truncate(0);
51        cx.pass_stack.push(pass_id);
52        
53        //let pass_size = cxpass.pass_size;
54        //self.set_ortho_matrix(cx, Vec2::zero(), pass_size);
55    }
56    
57    pub fn override_dpi_factor(&mut self, cx: &mut Cx, dpi_factor:f32){
58        if let Some(pass_id) = self.pass_id {
59            cx.passes[pass_id].override_dpi_factor = Some(dpi_factor);
60            cx.current_dpi_factor = dpi_factor;
61        }
62    }
63    
64    pub fn make_dep_of_pass(&mut self, cx: &mut Cx, pass: &Pass) {
65        let cxpass = &mut cx.passes[self.pass_id.unwrap()];
66        if let Some(pass_id) = pass.pass_id {
67            cxpass.dep_of = CxPassDepOf::Pass(pass_id)
68        }
69        else {
70            cxpass.dep_of = CxPassDepOf::None
71        }
72    }
73    
74    pub fn set_size(&mut self, cx: &mut Cx, pass_size: Vec2) {
75        let cxpass = &mut cx.passes[self.pass_id.unwrap()];
76        cxpass.pass_size = pass_size;
77    }
78    
79    pub fn add_color_texture(&mut self, cx: &mut Cx, texture: &mut Texture, clear_color: ClearColor) {
80        texture.set_desc(cx, None);
81        let pass_id = self.pass_id.expect("Please call add_color_texture after begin_pass");
82        let cxpass = &mut cx.passes[pass_id];
83        cxpass.color_textures.push(CxPassColorTexture {
84            texture_id: texture.texture_id.unwrap(),
85            clear_color: clear_color
86        })
87    }
88    
89    pub fn set_depth_texture(&mut self, cx: &mut Cx, texture: &mut Texture, clear_depth: ClearDepth) {
90        texture.set_desc(cx, None);
91        let pass_id = self.pass_id.expect("Please call set_depth_texture after begin_pass");
92        let cxpass = &mut cx.passes[pass_id];
93        cxpass.depth_texture = texture.texture_id;
94        cxpass.clear_depth = clear_depth;
95    }
96    
97    
98    pub fn end_pass(&mut self, cx: &mut Cx) {
99        cx.pass_stack.pop();
100        if cx.pass_stack.len()>0{
101            cx.current_dpi_factor = cx.get_delegated_dpi_factor(*cx.pass_stack.last().unwrap());
102        }
103    }
104    
105    pub fn redraw_pass_area(&mut self, cx: &mut Cx) {
106        if let Some(pass_id) = self.pass_id {
107            cx.redraw_pass_and_sub_passes(pass_id);
108        }
109    }
110    
111}
112
113#[derive(Clone)]
114pub enum ClearColor {
115    InitWith(Color),
116    ClearWith(Color)
117}
118
119impl Default for ClearColor {
120    fn default() -> Self {
121        ClearColor::ClearWith(Color::default())
122    }
123}
124
125#[derive(Clone)]
126pub enum ClearDepth {
127    InitWith(f64),
128    ClearWith(f64)
129}
130
131#[derive(Default, Clone)]
132pub struct CxPassColorTexture {
133    pub clear_color: ClearColor,
134    pub texture_id: usize
135}
136
137#[derive(Default, Clone)]
138#[repr(C)]
139pub struct PassUniforms{
140    camera_projection:[f32;16],
141    camera_view:[f32;16],
142    dpi_factor:f32,
143    dpi_dilate:f32,
144    pad1:f32,
145    pad2:f32
146}
147
148impl PassUniforms{
149    pub fn as_slice(&self)->&[f32;std::mem::size_of::<PassUniforms>()]{
150        unsafe{std::mem::transmute(self)}
151    }
152}
153
154#[derive(Clone)]
155pub struct CxPass {
156    pub color_textures: Vec<CxPassColorTexture>,
157    pub depth_texture: Option<usize>,
158    pub clear_depth: ClearDepth,
159    pub depth_init: f64,
160    pub override_dpi_factor: Option<f32>,
161    pub main_view_id: Option<usize>,
162    pub dep_of: CxPassDepOf,
163    pub paint_dirty: bool,
164    pub pass_size: Vec2,
165    pub pass_uniforms: PassUniforms,
166    pub zbias_step: f32,
167    pub platform: CxPlatformPass,
168}
169
170impl Default for CxPass {
171    fn default() -> Self {
172        CxPass {
173            zbias_step: 0.001,
174            pass_uniforms: PassUniforms::default(),
175            color_textures: Vec::new(),
176            depth_texture: None,
177            override_dpi_factor: None,
178            clear_depth: ClearDepth::ClearWith(1.0),
179            depth_init: 1.0,
180            main_view_id: None,
181            dep_of: CxPassDepOf::None,
182            paint_dirty: false,
183            pass_size: Vec2::default(),
184            platform: CxPlatformPass::default()
185        }
186    }
187}
188
189#[derive(Clone, Debug)]
190pub enum CxPassDepOf {
191    Window(usize),
192    Pass(usize),
193    None
194}
195
196
197impl CxPass {
198    pub fn def_uniforms(sg: ShaderGen) -> ShaderGen {
199        sg.compose(shader_ast!({
200            let camera_projection: mat4<PassUniform>;
201            let camera_view: mat4<PassUniform>;
202            let dpi_factor: float<PassUniform>;
203            let dpi_dilate: float<PassUniform>;
204        }))
205    }
206    
207    pub fn uniform_camera_projection(&mut self, v: &Mat4) {
208        //dump in uniforms
209        for i in 0..16 {
210            self.pass_uniforms.camera_projection[i] = v.v[i];
211        }
212    }
213    
214    pub fn uniform_camera_view(&mut self, v: &Mat4) {
215        //dump in uniforms
216        for i in 0..16 {
217            self.pass_uniforms.camera_view[i] =  v.v[i];
218        }
219    }
220    
221    pub fn set_dpi_factor(&mut self, dpi_factor: f32) {
222        let dpi_dilate = (2. - dpi_factor).max(0.).min(1.);
223        self.pass_uniforms.dpi_factor = dpi_factor;
224        self.pass_uniforms.dpi_dilate = dpi_dilate;
225    }
226    
227    pub fn set_ortho_matrix(&mut self, offset: Vec2, size: Vec2) {
228        let ortho_matrix = Mat4::ortho(
229            offset.x,
230            offset.x + size.x,
231            offset.y,
232            offset.y + size.y,
233            100.,
234            -100.,
235            1.0,
236            1.0
237        );
238        
239        //println!("{} {}", ortho_matrix.v[10], ortho_matrix.v[14]);
240        //println!("CHECK {} {} {:?}", size.x, size.y,ortho_matrix.transform_vec4(Vec4{x:200.,y:300.,z:100.,w:1.0}));
241        self.uniform_camera_projection(&ortho_matrix);
242        //self.set_matrix(cx, &ortho_matrix);
243    }
244    
245    //pub fn set_matrix(&mut self, cx: &mut Cx, matrix: &Mat4) {
246    //let pass_id = self.pass_id.expect("Please call set_ortho_matrix after begin_pass");
247    //let cxpass = &mut cx.passes[pass_id];
248    // }
249}