Skip to main content

example_4_2d_camera/
example_4_2d_camera.rs

1//! Does exactly the same as example 3, but also introduces *uniforms*: a way of sending a variable
2//! to be used in *every* point in the vertex/fragment shader.
3//! In this example, it's used to control a global 'position offset', which is subtracted from each
4//! vertex position to act as a 'camera' moving.
5
6// This example assumes you have also read example 3: colorful triangle.
7// Many things are not explained here as they were explained in the last
8// example. This example builds upon example 3.
9// <https://github.com/dylanopen/realms/tree/main/examples/example3_colorful_triangle>
10
11use realms::data::Color;
12use realms::input::{Event, Key};
13use realms::shader::{Shader, ShaderProgram, ShaderType};
14use realms::vertex::VertexBuffer;
15use realms::window::Window;
16
17fn main() {
18    let mut window = Window::new(800, 600, "We Have A Camera?").expect("Failed to create window");
19
20    let shader_program = ShaderProgram::new(vec![
21        Shader::load_str(ShaderType::Vertex, include_str!("shaders/vertex4.glsl")).unwrap(),
22        Shader::load_str(ShaderType::Fragment, include_str!("shaders/fragment4.glsl")).unwrap(),
23    ])
24    .unwrap();
25    // NOTE: the vertex shader has  changed since example 3. Please update
26    // `vertex2.glsl` using the new versions of it in this directory.
27    // The fragment shader has stayed the same.
28
29    // all vertices are the same as in the last example
30    let vertices: [f32; 15] = [
31        //   X     Y     red green blue
32        0.0, 0.5, 0.0, 1.0, 0.0, // top of triangle, green
33        -0.5, -0.5, 1.0, 0.0, 0.0, // bottom left of triangle, red
34        0.5, -0.5, 0.0, 0.0, 1.0, // bottom right of triangle, blue
35    ];
36
37    let elements: [u32; 3] = [0, 1, 2];
38
39    let vb = VertexBuffer::new(&vertices, &elements);
40
41    // same attribute layout as in the last example:
42    vb.set_layout(&[2, 3]);
43
44    let (mut camera_x, mut camera_y) = (0.0, 0.0); // --NEW-- //
45
46    while window.is_running() {
47        window.new_frame();
48        window.fill(Color::rgb(20, 34, 40));
49
50        // --- NEW --- //
51        for event in window.events() {
52            match event {
53                // here, we don't store the current state of the key, so we
54                // need to move the camera by repeatedly pressing WASD.
55                Event::KeyDown(Key::W) => camera_y += 0.1, // move camera up
56                Event::KeyDown(Key::S) => camera_y -= 0.1, // move camera down
57                Event::KeyDown(Key::A) => camera_x -= 0.1, // move camera left
58                Event::KeyDown(Key::D) => camera_x += 0.1, // move camera right
59                _ => {}
60            }
61        }
62        // upload the camera position to the vertex shader using a *uniform*:
63        // learn more: https://thebookofshaders.com/03/
64        shader_program.uniform_2f("cameraPos", (camera_x, camera_y));
65        // --- END NEW --- //
66
67        vb.draw(&shader_program); // draw the data in our vertex buffer
68    }
69}
70
71// NOTE: as we are moving the camera, the triangle will be moved opposite to
72// what we would expect (e.g. pressing 'left' moves the triangle right).
73// This is because we are moving the camera, which direction opposes that of
74// the shapes it views.