makepad_draw/shader/
draw_cube.rs

1use {
2    crate::{
3        makepad_platform::*,
4        draw_list_2d::ManyInstances,
5        geometry::GeometryCube3D,
6        cx_draw::CxDraw,
7    },
8};
9
10live_design!{
11    use link::shaders::*;
12    pub DrawCube = {{DrawCube}} {
13        
14        varying lit_color: vec4;
15        varying world: vec4,
16        
17        fn vertex(self) -> vec4 {
18            let pos = self.get_size() * self.geom_pos + self.get_pos();
19            let model_view = self.view_transform * self.transform;
20            
21            let normal_matrix = mat3(model_view);
22            let normal = normalize(normal_matrix * self.geom_normal);
23            let dp = max(dot(normal, normalize(vec3(0.0,1.0,1.0))), 0.0);
24
25            self.lit_color = self.get_color(dp);
26            self.world = model_view * vec4(pos, 1.);
27            return self.camera_projection * (self.camera_view * (self.world))
28        }
29        
30        fn get_size(self)->vec3{
31            return self.cube_size 
32        }
33        
34        fn get_pos(self)->vec3{
35            return self.cube_pos
36        }
37                
38        fn get_color(self, dp: float)->vec4{
39            let ambient = vec3(0.2,0.2,0.2)
40            let color = self.color.xyz * dp * self.color.w + ambient;
41            return vec4(color, self.color.w);
42        }
43        
44        fn pixel(self) -> vec4 {
45            return self.lit_color;
46        }
47        
48        fn fragment(self)->vec4{
49            return depth_clip(self.world, self.pixel(), self.depth_clip);
50        }
51    }
52}
53
54#[derive(Live, LiveRegister)]
55#[repr(C)]
56pub struct DrawCube {
57    #[rust] pub many_instances: Option<ManyInstances>,
58    #[live] pub geometry: GeometryCube3D,
59    #[deref] pub draw_vars: DrawVars,
60    #[live] pub color: Vec4,
61    #[calc] pub transform: Mat4,
62    #[live(vec3(1.0,1.0,1.0))] pub cube_size: Vec3,
63    #[live(vec3(0.,0.,0.))] pub cube_pos: Vec3,
64    #[live(0.0)] pub life: f32,
65    #[live(0.0)] pub index: f32,
66    #[live(1.0)] pub depth_clip: f32,
67}
68
69impl LiveHook for DrawCube{
70    fn before_apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]){
71        self.draw_vars.before_apply_init_shader(cx, apply, index, nodes, &self.geometry);
72    }
73    fn after_apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) {
74        self.draw_vars.after_apply_update_self(cx, apply, index, nodes, &self.geometry);
75    }
76}
77
78impl DrawCube {
79
80    pub fn draw(&mut self, cx: &mut CxDraw) {
81        if let Some(mi) = &mut self.many_instances {
82            mi.instances.extend_from_slice(self.draw_vars.as_slice());
83        }
84        else if self.draw_vars.can_instance() {
85            let new_area = cx.add_instance(&self.draw_vars);
86            self.draw_vars.area = cx.update_area_refs(self.draw_vars.area, new_area);
87        }
88    }
89    
90    pub fn new_draw_call(&self, cx: &mut CxDraw) {
91        cx.new_draw_call(&self.draw_vars);
92    }
93    
94    pub fn begin_many_instances(&mut self, cx: &mut CxDraw) {
95        let mi = cx.begin_many_instances(&self.draw_vars);
96        self.many_instances = mi;
97    }
98    
99    pub fn end_many_instances(&mut self, cx: &mut CxDraw) {
100        if let Some(mi) = self.many_instances.take() {
101            let new_area = cx.end_many_instances(mi);
102            self.draw_vars.area = cx.update_area_refs(self.draw_vars.area, new_area);
103        }
104    }
105}