shader/
shader.rs

1use std::f32::consts::PI;
2
3use bottomless_pit::colour::Colour;
4use bottomless_pit::engine_handle::{Engine, EngineBuilder};
5use bottomless_pit::material::{Material, MaterialBuilder};
6use bottomless_pit::render::RenderHandle;
7use bottomless_pit::resource::LoadingOp;
8use bottomless_pit::shader::{Shader, ShaderOptions, UniformData};
9use bottomless_pit::vec2;
10use bottomless_pit::vectors::Vec2;
11use bottomless_pit::Game;
12
13use encase::ShaderType;
14
15fn main() {
16    let mut engine = EngineBuilder::new().build().unwrap();
17
18    let data = MousePos {
19        x: 0.0,
20        y: 0.0,
21        _junk: 0.0,
22        _padding2: 0.0,
23    };
24
25    let mouse_uniform_data = UniformData::new(&data);
26    let mouse_shader = Shader::new(
27        "examples/mouse.wgsl",
28        ShaderOptions::with_uniform_data(&mouse_uniform_data),
29        &mut engine,
30        LoadingOp::Blocking,
31    );
32
33    // On wasm we need this to be 16 bytes aligned so we have added this instead of
34    // a 0.0_f32
35    let circle_uniform_data = UniformData::new(&data);
36    let circle_shader = Shader::new(
37        "examples/movement.wgsl",
38        ShaderOptions::with_uniform_data(&circle_uniform_data),
39        &mut engine,
40        LoadingOp::Blocking,
41    );
42
43    let mouse_material = MaterialBuilder::new()
44        .set_shader(mouse_shader)
45        .build(&mut engine);
46
47    let circle_material = MaterialBuilder::new()
48        .set_shader(circle_shader)
49        .build(&mut engine);
50
51    let defualt_material = MaterialBuilder::new().build(&mut engine);
52
53    let game = ShaderExample {
54        data,
55        mouse_material,
56        circle_material,
57        defualt_material,
58        theta: data,
59    };
60
61    engine.run(game);
62}
63
64#[derive(ShaderType, Clone, Copy)]
65struct MousePos {
66    x: f32,
67    y: f32,
68    _junk: f32,
69    _padding2: f32,
70}
71
72struct ShaderExample {
73    mouse_material: Material<MousePos>,
74    circle_material: Material<MousePos>,
75    defualt_material: Material,
76    data: MousePos,
77    theta: MousePos,
78}
79
80impl Game for ShaderExample {
81    fn render<'o>(&'o mut self, mut render: RenderHandle<'o>) {
82        let mut render_handle = render.begin_pass(Colour::BLACK);
83
84        self.mouse_material.add_rectangle(
85            vec2! { 0.0 },
86            vec2! { 100.0 },
87            Colour::RED,
88            &render_handle,
89        );
90        self.circle_material.add_rectangle(
91            vec2! { 100.0 },
92            vec2! { 100.0 },
93            Colour::RED,
94            &render_handle,
95        );
96        self.defualt_material.add_rectangle(
97            Vec2 { x: 0.0, y: 200.0 },
98            vec2! { 100.0 },
99            Colour::RED,
100            &render_handle,
101        );
102
103        self.mouse_material.draw(&mut render_handle);
104        self.circle_material.draw(&mut render_handle);
105        self.defualt_material.draw(&mut render_handle);
106    }
107
108    fn update(&mut self, engine_handle: &mut Engine) {
109        let dt = engine_handle.get_frame_delta_time();
110
111        self.theta.x = (self.theta.x + dt) % (2.0 * PI);
112
113        let size = engine_handle.get_window_size();
114        let mouse_pos = engine_handle.get_mouse_position();
115
116        let new_data = MousePos {
117            x: mouse_pos.x / size.x as f32,
118            y: mouse_pos.y / size.y as f32,
119            _junk: 0.0,
120            _padding2: 0.0,
121        };
122
123        self.data = new_data;
124        self.mouse_material
125            .update_uniform_data(&self.data, &engine_handle)
126            .unwrap();
127        self.circle_material
128            .update_uniform_data(&self.theta, &engine_handle)
129            .unwrap();
130    }
131}