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.