moving_triangle/
moving_triangle.rs

1use std::iter::once;
2
3use wgpu::{CommandEncoder, PresentMode, RenderPipeline, TextureView, VertexAttribute};
4
5use wgpu_noboiler::app::{AppCreator, AppData};
6use wgpu_noboiler::buffer::BufferCreator;
7use wgpu_noboiler::render_pass::RenderPassCreator;
8use wgpu_noboiler::render_pipeline::RenderPipelineCreator;
9use wgpu_noboiler::vertex::Vertex;
10
11#[repr(C)]
12#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
13struct ColoredPosVertex {
14    position: [f32; 2],
15}
16
17impl Vertex<1> for ColoredPosVertex {
18    const ATTRIBS: [VertexAttribute; 1] = wgpu::vertex_attr_array![0 => Float32x2];
19}
20
21struct State {
22    pos: (f32, f32),
23    vel: (f32, f32),
24    x_scale: f32,
25}
26
27const TRIANGLE_SIZE: f32 = 0.3;
28
29fn main() {
30    AppCreator::new(State {
31        pos: (0.5, 0.0),
32        vel: (0.707, 0.707),
33        x_scale: 9.0 / 16.0,
34    })
35        .init(init)
36        .render(render)
37        .update(update)
38        .resize(resize)
39        .present_mode(PresentMode::Immediate)
40        .run()
41}
42
43fn render(app_data: &AppData, state: &mut State, mut encoder: CommandEncoder, view: TextureView) {
44    let vertex_buffer = BufferCreator::vertex(&app_data.device)
45        .data(vec![
46            ColoredPosVertex {
47                position: [
48                    (0.0 + state.pos.0) * state.x_scale,
49                    TRIANGLE_SIZE + state.pos.1,
50                ],
51            },
52            ColoredPosVertex {
53                position: [
54                    (-TRIANGLE_SIZE + state.pos.0) * state.x_scale,
55                    -TRIANGLE_SIZE + state.pos.1,
56                ],
57            },
58            ColoredPosVertex {
59                position: [
60                    (TRIANGLE_SIZE + state.pos.0) * state.x_scale,
61                    -TRIANGLE_SIZE + state.pos.1,
62                ],
63            },
64        ])
65        .build();
66
67    {
68        let mut render_pass = RenderPassCreator::new(&view).build(&mut encoder);
69
70        render_pass.set_pipeline(app_data.render_pipelines.get(0).unwrap());
71        render_pass.set_vertex_buffer(0, vertex_buffer.slice());
72
73        render_pass.draw(0..3, 0..1);
74    }
75
76    app_data.queue.submit(once(encoder.finish()));
77}
78
79fn update(app_data: &AppData, state: &mut State) {
80    if state.pos.0.abs() > 1.0 / state.x_scale - TRIANGLE_SIZE {
81        state.vel.0 = -state.vel.0;
82    }
83
84    if state.pos.1.abs() > (1.0 - TRIANGLE_SIZE) {
85        state.vel.1 = -state.vel.1;
86    }
87
88    state.pos.0 += state.vel.0 * app_data.delta_time as f32;
89    state.pos.1 += state.vel.1 * app_data.delta_time as f32;
90}
91
92fn resize(_: &AppData, state: &mut State, size: (u32, u32)) {
93    state.x_scale = size.1 as f32 / size.0 as f32;
94}
95
96fn init(app_data: &AppData, _state: &mut State, vec: &mut Vec<RenderPipeline>) {
97    let render_pipeline = RenderPipelineCreator::from_shader_file(
98        "examples/shaderColorFromPos.wgsl",
99        &app_data.device,
100        &app_data.config,
101    )
102        .add_vertex_buffer(ColoredPosVertex::descriptor())
103        .build();
104
105    vec.push(render_pipeline);
106}