makepad_render/
area.rs

1use crate::cx::*; 
2
3#[derive(Clone, Default, Debug, PartialEq, Copy)]
4pub struct InstanceArea{
5    pub view_id:usize,
6    pub draw_call_id:usize,
7    pub instance_offset:usize,
8    pub instance_count:usize,
9    pub redraw_id:u64
10}
11
12#[derive(Clone, Default, Debug, PartialEq, Copy)]
13pub struct ViewArea{
14    pub view_id:usize,
15    pub redraw_id:u64 
16}
17
18#[derive(Clone, Debug, PartialEq, Copy)]
19pub enum Area{
20    Empty,
21    All,
22    Instance(InstanceArea),
23    View(ViewArea)
24}
25
26impl Default for Area{
27    fn default()->Area{
28        Area::Empty
29    } 
30}  
31
32pub struct InstanceReadRef<'a>{
33    pub offset:usize,
34    pub slots:usize,
35    pub count:usize, 
36    pub buffer:&'a Vec<f32>
37}
38
39pub struct InstanceWriteRef<'a>{
40    pub offset:usize,
41    pub slots:usize,
42    pub count:usize,
43    pub buffer:&'a mut Vec<f32>
44}
45
46impl Area{
47    pub fn is_empty(&self)->bool{
48        if let Area::Empty = self{
49            return true
50        }
51        false
52    }
53
54    pub fn is_valid(&self, cx:&Cx)->bool{
55        return match self{
56            Area::Instance(inst)=>{
57                if inst.instance_count == 0{
58                    return false
59                }
60                let cxview = &cx.views[inst.view_id];
61                if cxview.redraw_id != inst.redraw_id {
62                    return false
63                }
64                return true
65            },
66            Area::View(view_area)=>{
67                let cxview = &cx.views[view_area.view_id];
68                if cxview.redraw_id != view_area.redraw_id {
69                    return false
70                }
71                return true
72            },
73            _=>false,
74        }
75    }
76    
77    pub fn get_local_scroll_pos(&self, cx:&Cx)->Vec2{
78        return match self{
79            Area::Instance(inst)=>{
80                let cxview = &cx.views[inst.view_id];
81                if cxview.redraw_id != inst.redraw_id {
82                    Vec2::default()
83                }
84                else{
85                    cxview.unsnapped_scroll
86                }
87            },
88            Area::View(view_area)=>{
89                let cxview = &cx.views[view_area.view_id];
90                cxview.unsnapped_scroll
91            },
92            _=>Vec2::default(),
93        }
94    }
95
96    pub fn get_scroll_pos(&self, cx:&Cx)->Vec2{
97        return match self{
98            Area::Instance(inst)=>{
99                let cxview = &cx.views[inst.view_id];
100                if cxview.redraw_id != inst.redraw_id {
101                    Vec2::default()
102                }
103                else{
104                    let draw_call = &cxview.draw_calls[inst.draw_call_id];
105                    Vec2{
106                        x:draw_call.draw_uniforms.draw_scroll_x,
107                        y:draw_call.draw_uniforms.draw_scroll_y
108                    }
109                }
110            },
111            Area::View(view_area)=>{
112                let cxview = &cx.views[view_area.view_id];
113                cxview.parent_scroll
114            },
115            _=>Vec2::default(),
116        }
117    }
118    // returns the final screen rect
119    pub fn get_rect(&self, cx:&Cx)->Rect{
120
121        return match self{
122            Area::Instance(inst)=>{
123                if inst.instance_count == 0{
124                    println!("get_rect called on instance_count ==0 area pointer, use mark/sweep correctly!");
125                    return Rect::default()
126                }
127                let cxview = &cx.views[inst.view_id];
128                if cxview.redraw_id != inst.redraw_id {
129                    return Rect::default();
130                }
131                let draw_call = &cxview.draw_calls[inst.draw_call_id];
132                let sh = &cx.shaders[draw_call.shader_id];
133                // ok now we have to patch x/y/w/h into it
134                if let Some(ix) = sh.mapping.rect_instance_props.x{
135                    let x = draw_call.instance[inst.instance_offset + ix];
136                    if let Some(iy) = sh.mapping.rect_instance_props.y{
137                        let y = draw_call.instance[inst.instance_offset + iy];
138                        if let Some(iw) = sh.mapping.rect_instance_props.w{
139                            let w = draw_call.instance[inst.instance_offset + iw];
140                            if let Some(ih) = sh.mapping.rect_instance_props.h{
141                                let h = draw_call.instance[inst.instance_offset + ih];
142                                return draw_call.clip_and_scroll_rect(x,y,w,h);
143                            }
144                        }
145                    }
146                }
147                Rect::default()
148            },
149            Area::View(view_area)=>{
150                let cxview = &cx.views[view_area.view_id];
151                Rect{
152                    x:cxview.rect.x - cxview.parent_scroll.x,
153                    y:cxview.rect.y - cxview.parent_scroll.y,
154                    w:cxview.rect.w,
155                    h:cxview.rect.h
156                }
157            },
158            _=>Rect::default(),
159        }
160    }
161
162    pub fn abs_to_rel(&self, cx:&Cx, abs:Vec2)->Vec2{
163        return match self{
164            Area::Instance(inst)=>{
165                if inst.instance_count == 0{
166                    println!("abs_to_rel_scroll called on instance_count ==0 area pointer, use mark/sweep correctly!");
167                    return abs
168                }
169                let cxview = &cx.views[inst.view_id];
170                if cxview.redraw_id != inst.redraw_id {
171                    return abs;
172                }
173                let draw_call = &cxview.draw_calls[inst.draw_call_id];
174                let sh = &cx.shaders[draw_call.shader_id];
175                // ok now we have to patch x/y/w/h into it
176                if let Some(ix) = sh.mapping.rect_instance_props.x{
177                    let x = draw_call.instance[inst.instance_offset + ix];
178                    if let Some(iy) = sh.mapping.rect_instance_props.y{
179                        let y = draw_call.instance[inst.instance_offset + iy];
180                        return Vec2{
181                            x:abs.x - x + draw_call.draw_uniforms.draw_scroll_x,
182                            y:abs.y - y + draw_call.draw_uniforms.draw_scroll_y
183                        }
184                    }
185                }
186                abs
187            },
188            Area::View(view_area)=>{
189                let cxview = &cx.views[view_area.view_id];
190                return Vec2{
191                    x:abs.x - cxview.rect.x + cxview.parent_scroll.x + cxview.unsnapped_scroll.x,
192                    y:abs.y - cxview.rect.y - cxview.parent_scroll.y + cxview.unsnapped_scroll.y
193                }
194            },
195            _=>abs,
196        }
197    }
198
199    pub fn set_rect(&self, cx:&mut Cx, rect:&Rect){
200         match self{
201            Area::Instance(inst)=>{
202                let cxview = &mut cx.views[inst.view_id];
203                if cxview.redraw_id != inst.redraw_id {
204                    println!("set_rect called on invalid area pointer, use mark/sweep correctly!");
205                    return;
206                }
207                let draw_call = &mut cxview.draw_calls[inst.draw_call_id];
208                let sh = &cx.shaders[draw_call.shader_id];        // ok now we have to patch x/y/w/h into it
209                
210                if let Some(ix) = sh.mapping.rect_instance_props.x{
211                    draw_call.instance[inst.instance_offset + ix] = rect.x;
212                }
213                if let Some(iy) = sh.mapping.rect_instance_props.y{
214                    draw_call.instance[inst.instance_offset + iy] = rect.y;
215                }
216                if let Some(iw) = sh.mapping.rect_instance_props.w{
217                    draw_call.instance[inst.instance_offset + iw] = rect.w;
218                }
219                if let Some(ih) = sh.mapping.rect_instance_props.h{
220                    draw_call.instance[inst.instance_offset + ih] = rect.h;
221                }
222            },
223            Area::View(view_area)=>{
224                let cxview = &mut cx.views[view_area.view_id];
225                cxview.rect = rect.clone()
226            },
227            _=>()
228         }
229    }
230
231    pub fn get_instance_offset(&self, cx:&Cx, prop_ident:InstanceType)->Option<usize>{
232        match self{
233            Area::Instance(inst)=>{
234                let cxview = &cx.views[inst.view_id];
235                let draw_call = &cxview.draw_calls[inst.draw_call_id];
236                let sh = &cx.shaders[draw_call.shader_id];
237                for prop in &sh.mapping.instance_props.props{
238                    if prop.ident == prop_ident{
239                        return Some(prop.offset)
240                    }
241                }
242            }
243            _=>(),
244        }
245        None
246    }
247
248    pub fn get_uniform_offset(&self, cx:&Cx, prop_ident:UniformType)->Option<usize>{
249        match self{
250            Area::Instance(inst)=>{
251                let cxview = &cx.views[inst.view_id];
252                let draw_call = &cxview.draw_calls[inst.draw_call_id];
253                let sh = &cx.shaders[draw_call.shader_id];
254                for prop in &sh.mapping.uniform_props.props{
255                    if prop.ident == prop_ident{
256                        return Some(prop.offset)
257                    }
258                }
259                /*
260                let mut dbg = String::new();
261                for prop in &sh.mapping.uniform_props.props{
262                    dbg.push_str(&format!("name:{} offset:{}, ", prop.name, prop.offset));
263                }
264                println!("get_uniform_offset not found in [{}]", dbg);*/
265            }
266            _=>(),
267        }
268        //println!("get_uniform_offset {} called on invalid prop", prop_name);
269        None
270    }
271
272
273    pub fn get_read_ref<'a>(&self, cx:&'a Cx)->Option<InstanceReadRef<'a>>{
274        match self{
275            Area::Instance(inst)=>{
276                let cxview = &cx.views[inst.view_id];
277                let draw_call = &cxview.draw_calls[inst.draw_call_id];
278                if cxview.redraw_id != inst.redraw_id {
279                    println!("get_read_ref alled on invalid area pointer, use mark/sweep correctly!");
280                    return None;
281                }
282                let sh = &cx.shaders[draw_call.shader_id];
283                return Some(
284                    InstanceReadRef{
285                        offset:inst.instance_offset, 
286                        count:inst.instance_count, 
287                        slots:sh.mapping.instance_slots,
288                        buffer:&draw_call.instance
289                    }
290                )
291            }
292            _=>(),
293        }
294        return None;
295    }
296
297    pub fn get_write_ref<'a>(&self, cx:&'a mut Cx)->Option<InstanceWriteRef<'a>>{
298        match self{
299            Area::Instance(inst)=>{
300                let cxview = &mut cx.views[inst.view_id];
301                let draw_call = &mut cxview.draw_calls[inst.draw_call_id];
302                if cxview.redraw_id != inst.redraw_id {
303                    //println!("get_write_ref called on invalid area pointer, use mark/sweep correctly!");
304                    return None;
305                }
306                let sh = &cx.shaders[draw_call.shader_id];
307                cx.passes[cxview.pass_id].paint_dirty = true;
308                draw_call.instance_dirty = true;
309                return Some(
310                    InstanceWriteRef{
311                        offset:inst.instance_offset, 
312                        count:inst.instance_count, 
313                        slots:sh.mapping.instance_slots,
314                        buffer:&mut draw_call.instance
315                    }
316                )
317            }
318            _=>(),
319        }
320        return None;
321    }
322
323    pub fn get_uniform_write_ref<'a>(&self, cx:&'a mut Cx)->Option<&'a mut Vec<f32>>{
324        match self{
325            Area::Instance(inst)=>{
326                let cxview = &mut cx.views[inst.view_id];
327                let draw_call = &mut cxview.draw_calls[inst.draw_call_id];
328                if cxview.redraw_id != inst.redraw_id {
329                    return None;
330                }
331                cx.passes[cxview.pass_id].paint_dirty = true;
332                draw_call.uniforms_dirty = true;
333                return Some(
334                    &mut draw_call.uniforms
335                )
336            }
337            _=>(),
338        }
339        return None;
340    }
341
342    pub fn write_float(&self, cx:&mut Cx, prop_ident:InstanceFloat, value:f32){
343        if let Some(inst_offset) = self.get_instance_offset(cx, InstanceType::Float(prop_ident)){
344            let write = self.get_write_ref(cx);
345            if let Some(write) = write{
346                for i in 0..write.count{
347                    write.buffer[write.offset + inst_offset + i * write.slots] = value;
348                }
349            }
350        }
351    }
352
353    pub fn read_float(&self, cx:&Cx, prop_ident:InstanceFloat)->f32{
354        if let Some(inst_offset) = self.get_instance_offset(cx, InstanceType::Float(prop_ident)){
355            let read = self.get_read_ref(cx);
356            if let Some(read) = read{
357                return read.buffer[read.offset + inst_offset]
358            }
359        }
360        0.0
361    }
362
363   pub fn write_vec2(&self, cx:&mut Cx, prop_ident:InstanceVec2, value:Vec2){
364        if let Some(inst_offset) = self.get_instance_offset(cx, InstanceType::Vec2(prop_ident)){
365            let write = self.get_write_ref(cx);
366            if let Some(write) = write{
367                for i in 0..write.count{
368                    write.buffer[write.offset + inst_offset + 0 + i * write.slots] = value.y;
369                    write.buffer[write.offset + inst_offset + 1 + i * write.slots] = value.x;
370                }
371            }
372        }
373   }
374
375    pub fn read_vec2(&self, cx:&Cx, prop_ident:InstanceVec2)->Vec2{
376        if let Some(inst_offset) = self.get_instance_offset(cx, InstanceType::Vec2(prop_ident)){
377            let read = self.get_read_ref(cx);
378            if let Some(read) = read{
379                return Vec2{
380                    x:read.buffer[read.offset + inst_offset + 0],
381                    y:read.buffer[read.offset + inst_offset + 1]
382                }
383            }
384        }
385        Vec2::default()
386    }
387
388   pub fn write_vec3(&self, cx:&mut Cx, prop_ident:InstanceVec3, value:Vec3){
389        if let Some(inst_offset) = self.get_instance_offset(cx, InstanceType::Vec3(prop_ident)){
390            let write = self.get_write_ref(cx);
391            if let Some(write) = write{
392                for i in 0..write.count{
393                    write.buffer[write.offset + inst_offset + 0 + i * write.slots] = value.y;
394                    write.buffer[write.offset + inst_offset + 1 + i * write.slots] = value.x;
395                    write.buffer[write.offset + inst_offset + 2 + i * write.slots] = value.z;
396                }
397            }
398        }
399    }
400
401    pub fn read_vec3(&self, cx:&Cx, prop_ident:InstanceVec3)->Vec3{
402        if let Some(inst_offset) = self.get_instance_offset(cx, InstanceType::Vec3(prop_ident)){
403            let read = self.get_read_ref(cx);
404            if let Some(read) = read{
405                return Vec3{
406                    x:read.buffer[read.offset + inst_offset + 0],
407                    y:read.buffer[read.offset + inst_offset + 1],
408                    z:read.buffer[read.offset + inst_offset + 2]
409                }
410            }
411        }
412        Vec3::default()
413    }
414
415   pub fn write_vec4(&self, cx:&mut Cx, prop_ident:InstanceVec4, value:Vec4){
416        if let Some(inst_offset) = self.get_instance_offset(cx, InstanceType::Vec4(prop_ident)){
417            let write = self.get_write_ref(cx);
418            if let Some(write) = write{
419                for i in 0..write.count{
420                    write.buffer[write.offset + inst_offset + 0 + i * write.slots] = value.x;
421                    write.buffer[write.offset + inst_offset + 1 + i * write.slots] = value.y;
422                    write.buffer[write.offset + inst_offset + 2 + i * write.slots] = value.z;
423                    write.buffer[write.offset + inst_offset + 3 + i * write.slots] = value.w;
424                }
425            }
426        }
427   }
428
429    pub fn read_vec4(&self, cx:&Cx, prop_ident:InstanceVec4)->Vec4{
430        if let Some(inst_offset) = self.get_instance_offset(cx, InstanceType::Vec4(prop_ident)){
431            let read = self.get_read_ref(cx);
432            if let Some(read) = read{
433                return Vec4{
434                    x:read.buffer[read.offset + inst_offset + 0],
435                    y:read.buffer[read.offset + inst_offset + 1],
436                    z:read.buffer[read.offset + inst_offset + 2],
437                    w:read.buffer[read.offset + inst_offset + 3],
438                }
439            }
440        }
441        Vec4::default()
442    }
443
444    pub fn write_color(&self, cx:&mut Cx, prop_ident:InstanceColor, value:Color){
445        if let Some(inst_offset) = self.get_instance_offset(cx, InstanceType::Color(prop_ident)){
446            let write = self.get_write_ref(cx);
447            if let Some(write) = write{
448                for i in 0..write.count{
449                    write.buffer[write.offset + inst_offset + 0 + i * write.slots] = value.r;
450                    write.buffer[write.offset + inst_offset + 1 + i * write.slots] = value.g;
451                    write.buffer[write.offset + inst_offset + 2 + i * write.slots] = value.b;
452                    write.buffer[write.offset + inst_offset + 3 + i * write.slots] = value.a;
453                }
454            }
455        }
456   }
457
458    pub fn read_color(&self, cx:&Cx, prop_ident:InstanceColor)->Color{
459        if let Some(inst_offset) = self.get_instance_offset(cx, InstanceType::Color(prop_ident)){
460            let read = self.get_read_ref(cx);
461            if let Some(read) = read{
462                return Color{
463                    r:read.buffer[read.offset + inst_offset + 0],
464                    g:read.buffer[read.offset + inst_offset + 1],
465                    b:read.buffer[read.offset + inst_offset + 2],
466                    a:read.buffer[read.offset + inst_offset + 3],
467                }
468            }
469        }
470        Color::default()
471    }
472
473    pub fn write_uniform_float(&self, cx:&mut Cx, prop_ident:UniformFloat, v:f32){
474        if let Some(uni_offset) = self.get_uniform_offset(cx, UniformType::Float(prop_ident)){
475            let write = self.get_uniform_write_ref(cx);
476            if let Some(write) = write{
477                while uni_offset >= write.len(){
478                    write.push(0.);
479                }
480                write[uni_offset] = v;
481            }
482        }
483    }
484/*
485    pub fn push_uniform_vec2f(&self, cx:&mut Cx,  x:f32, y:f32){
486        let draw_list = &mut cx.draw_lists[self.draw_list_id];
487        if draw_list.redraw_id != self.redraw_id {
488            println!("uniform_vec2f called on invalid area pointer, use mark/sweep correctly!");
489            return
490        }
491        let draw_call = &mut draw_list.draw_calls[self.draw_call_id]; 
492        draw_call.uniforms.push(x);
493        draw_call.uniforms.push(y);
494    }
495
496    pub fn push_uniform_vec3f(&mut self, cx:&mut Cx, x:f32, y:f32, z:f32){
497        let draw_list = &mut cx.draw_lists[self.draw_list_id];
498        if draw_list.redraw_id != self.redraw_id {
499            println!("uniform_vec3f called on invalid area pointer, use mark/sweep correctly!");
500            return
501        }
502        let draw_call = &mut draw_list.draw_calls[self.draw_call_id]; 
503        draw_call.uniforms.push(x);
504        draw_call.uniforms.push(y);
505        draw_call.uniforms.push(z);
506    }
507
508    pub fn push_uniform_vec4f(&self, cx:&mut Cx, x:f32, y:f32, z:f32, w:f32){
509        let draw_list = &mut cx.draw_lists[self.draw_list_id];
510        if draw_list.redraw_id != self.redraw_id {
511            println!("uniform_vec4f called on invalid area pointer, use mark/sweep correctly!");
512            return
513        }
514        let draw_call = &mut draw_list.draw_calls[self.draw_call_id]; 
515        draw_call.uniforms.push(x);
516        draw_call.uniforms.push(y);
517        draw_call.uniforms.push(z);
518        draw_call.uniforms.push(w);
519    }
520
521    pub fn push_uniform_mat4(&self, cx:&mut Cx, v:&Mat4){
522        let draw_list = &mut cx.draw_lists[self.draw_list_id];
523        if draw_list.redraw_id != self.redraw_id {
524            println!("uniform_mat4 called on invalid area pointer, use mark/sweep correctly!");
525            return
526        }
527        let draw_call = &mut draw_list.draw_calls[self.draw_call_id]; 
528        for i in 0..16{
529            draw_call.uniforms.push(v.v[i]);
530        }
531    }    */
532}
533
534impl Into<Area> for InstanceArea{
535    fn into(self)->Area{
536        Area::Instance(self)
537    }
538}
539
540impl InstanceArea{
541    
542    pub fn push_slice(&self, cx:&mut Cx, data:&[f32]){
543        let cxview = &mut cx.views[self.view_id];
544        if cxview.redraw_id != self.redraw_id {
545            println!("push_data called on invalid area pointer, use mark/sweep correctly!");
546            return
547        }
548        let draw_call = &mut cxview.draw_calls[self.draw_call_id];
549        //let csh = &cx.shaders.compiled_shaders[draw_call.shader_id];
550        draw_call.instance.extend_from_slice(data);
551    }
552
553    pub fn push_last_float(&self, cx:&mut Cx, animator:&Animator, ident:InstanceFloat)->f32{
554        let ret = animator.last_float(cx, ident);
555        self.push_float(cx, ret);
556        ret
557    }
558
559    pub fn push_float(&self, cx:&mut Cx, value:f32){
560        let cxview = &mut cx.views[self.view_id];
561        if cxview.redraw_id != self.redraw_id {
562            println!("push_float called on invalid area pointer, use mark/sweep correctly!");
563            return
564        }
565        let draw_call = &mut cxview.draw_calls[self.draw_call_id];
566        //let csh = &cx.shaders.compiled_shaders[draw_call.shader_id];
567        draw_call.instance.push(value);
568    }
569
570    pub fn push_last_vec2(&self, cx:&mut Cx, animator:&Animator, ident:InstanceVec2)->Vec2{
571        let ret =  animator.last_vec2(cx, ident);
572        self.push_vec2(cx, ret);
573        ret
574    }
575
576    pub fn push_vec2(&self, cx:&mut Cx, value:Vec2){
577        let cxview = &mut cx.views[self.view_id];
578        if cxview.redraw_id != self.redraw_id {
579            println!("push_vec2 called on invalid area pointer, use mark/sweep correctly!");
580            return
581        }
582        let draw_call = &mut cxview.draw_calls[self.draw_call_id];
583        //let csh = &cx.shaders.compiled_shaders[draw_call.shader_id];
584        draw_call.instance.push(value.x);
585        draw_call.instance.push(value.y);
586    }
587
588    pub fn push_last_vec3(&self, cx:&mut Cx, animator:&Animator, ident:InstanceVec3)->Vec3{
589        let ret = animator.last_vec3(cx, ident);
590        self.push_vec3(cx, ret);
591        ret
592    }
593
594    pub fn push_vec3(&self, cx:&mut Cx, value:Vec3){
595        let cxview = &mut cx.views[self.view_id];
596        if cxview.redraw_id != self.redraw_id {
597            println!("push_vec3 called on invalid area pointer, use mark/sweep correctly!");
598            return
599        }
600        let draw_call = &mut cxview.draw_calls[self.draw_call_id];
601        draw_call.instance.push(value.x);
602        draw_call.instance.push(value.y);
603        draw_call.instance.push(value.z);
604    }
605
606    pub fn push_last_vec4(&self, cx:&mut Cx, animator:&Animator, ident:InstanceVec4)->Vec4{
607        let ret = animator.last_vec4(cx, ident);
608        self.push_vec4(cx, ret);
609        ret
610    }
611
612    pub fn push_vec4(&self, cx:&mut Cx, value:Vec4){
613        let cxview = &mut cx.views[self.view_id];
614        if cxview.redraw_id != self.redraw_id {
615            println!("push_vec4 called on invalid area pointer, use mark/sweep correctly!");
616            return
617        }
618        let draw_call = &mut cxview.draw_calls[self.draw_call_id];
619        draw_call.instance.push(value.x);
620        draw_call.instance.push(value.y);
621        draw_call.instance.push(value.z);
622        draw_call.instance.push(value.w);
623    }
624
625    pub fn push_last_color(&self, cx:&mut Cx, animator:&Animator, ident:InstanceColor)->Color{
626        let ret = animator.last_color(cx, ident);
627        self.push_color(cx, ret);
628        ret
629    }
630
631    pub fn push_color(&self, cx:&mut Cx, value:Color){
632        let cxview = &mut cx.views[self.view_id];
633        if cxview.redraw_id != self.redraw_id {
634            println!("push_vec4 called on invalid area pointer, use mark/sweep correctly!");
635            return
636        }
637        let draw_call = &mut cxview.draw_calls[self.draw_call_id];
638        draw_call.instance.push(value.r);
639        draw_call.instance.push(value.g);
640        draw_call.instance.push(value.b);
641        draw_call.instance.push(value.a);
642    }
643
644    pub fn set_do_scroll(&self, cx:&mut Cx, hor:bool, ver:bool){
645        let cxview = &mut cx.views[self.view_id];
646        if cxview.redraw_id != self.redraw_id {
647            println!("need_uniforms_now called on invalid area pointer, use mark/sweep correctly!");
648            return
649        }
650        let draw_call = &mut cxview.draw_calls[self.draw_call_id];
651        draw_call.do_h_scroll = hor;
652        draw_call.do_v_scroll = ver;
653    }
654
655    pub fn need_uniforms_now(&self, cx:&mut Cx)->bool{
656        let cxview = &mut cx.views[self.view_id];
657        if cxview.redraw_id != self.redraw_id {
658            println!("need_uniforms_now called on invalid area pointer, use mark/sweep correctly!");
659            return false
660        }
661        let draw_call = &mut cxview.draw_calls[self.draw_call_id];
662        //let csh = &cx.shaders.compiled_shaders[draw_call.shader_id];
663        return draw_call.need_uniforms_now()
664    }
665
666    pub fn push_uniform_texture_2d(&self, cx:&mut Cx,texture:&Texture){
667        let cxview = &mut cx.views[self.view_id];
668        if cxview.redraw_id != self.redraw_id {
669            println!("uniform_texture_2d called on invalid area pointer, use mark/sweep correctly!");
670            return
671        }
672        let draw_call = &mut cxview.draw_calls[self.draw_call_id]; 
673         if let Some(texture_id) = texture.texture_id{
674            draw_call.textures_2d.push(texture_id as u32);
675        }
676        else{
677            draw_call.textures_2d.push(0);
678        }
679    }
680
681    pub fn push_uniform_texture_2d_id(&self, cx:&mut Cx, texture_id: usize){
682        let cxview = &mut cx.views[self.view_id];
683        if cxview.redraw_id != self.redraw_id {
684            println!("uniform_texture_2d called on invalid area pointer, use mark/sweep correctly!");
685            return
686        }
687        let draw_call = &mut cxview.draw_calls[self.draw_call_id]; 
688        draw_call.textures_2d.push(texture_id as u32);
689    }
690
691    pub fn push_uniform_float(&self, cx:&mut Cx, v:f32){
692        let cxview = &mut cx.views[self.view_id];
693        if cxview.redraw_id != self.redraw_id {
694            println!("uniform_float called on invalid area pointer, use mark/sweep correctly!");
695            return
696        }
697        let draw_call = &mut cxview.draw_calls[self.draw_call_id]; 
698        draw_call.uniforms.push(v);
699    }
700
701    pub fn push_uniform_vec2(&self, cx:&mut Cx, v:Vec2){
702        let cxview = &mut cx.views[self.view_id];
703        if cxview.redraw_id != self.redraw_id {
704            println!("uniform_vec2f called on invalid area pointer, use mark/sweep correctly!");
705            return
706        }
707        let draw_call = &mut cxview.draw_calls[self.draw_call_id]; 
708        let left = draw_call.uniforms.len()&3;
709        if left > 2{ // align buffer
710            for _ in 0..(4-left){
711                draw_call.uniforms.push(0.0);
712            }
713        }
714        draw_call.uniforms.push(v.x);
715        draw_call.uniforms.push(v.y);
716    }
717
718    pub fn push_uniform_vec2f(&self, cx:&mut Cx,  x:f32, y:f32){
719        let cxview = &mut cx.views[self.view_id];
720        if cxview.redraw_id != self.redraw_id {
721            println!("uniform_vec2f called on invalid area pointer, use mark/sweep correctly!");
722            return
723        }
724        let draw_call = &mut cxview.draw_calls[self.draw_call_id]; 
725        let left = draw_call.uniforms.len()&3;
726        if left > 2{ // align buffer
727            for _ in 0..(4-left){
728                draw_call.uniforms.push(0.0);
729            }
730        }
731        draw_call.uniforms.push(x);
732        draw_call.uniforms.push(y);
733    }
734
735    pub fn push_uniform_vec3f(&mut self, cx:&mut Cx, x:f32, y:f32, z:f32){
736        let cxview = &mut cx.views[self.view_id];
737        if cxview.redraw_id != self.redraw_id {
738            println!("uniform_vec3f called on invalid area pointer, use mark/sweep correctly!");
739            return
740        }
741        let draw_call = &mut cxview.draw_calls[self.draw_call_id]; 
742        let left = draw_call.uniforms.len()&3;
743        if left > 1{ // align buffer
744            for _ in 0..(4-left){
745                draw_call.uniforms.push(0.0);
746            }
747        }
748        draw_call.uniforms.push(x);
749        draw_call.uniforms.push(y);
750        draw_call.uniforms.push(z);
751    }
752
753    pub fn push_uniform_vec4f(&self, cx:&mut Cx, x:f32, y:f32, z:f32, w:f32){
754        let cxview = &mut cx.views[self.view_id];
755        if cxview.redraw_id != self.redraw_id {
756            println!("uniform_vec4f called on invalid area pointer, use mark/sweep correctly!");
757            return
758        }
759        let draw_call = &mut cxview.draw_calls[self.draw_call_id]; 
760        let left = draw_call.uniforms.len()&3;
761        if left > 0{ // align buffer
762            for _ in 0..(4-left){
763                draw_call.uniforms.push(0.0);
764            }
765        }
766        draw_call.uniforms.push(x);
767        draw_call.uniforms.push(y);
768        draw_call.uniforms.push(z);
769        draw_call.uniforms.push(w);
770    }
771
772    pub fn push_uniform_mat4(&self, cx:&mut Cx, v:&Mat4){
773        let cxview = &mut cx.views[self.view_id];
774        if cxview.redraw_id != self.redraw_id {
775            println!("uniform_mat4 called on invalid area pointer, use mark/sweep correctly!");
776            return
777        }
778        let draw_call = &mut cxview.draw_calls[self.draw_call_id]; 
779        for i in 0..16{
780            draw_call.uniforms.push(v.v[i]);
781        }
782    }
783}