pub struct VertexBuffer { /* private fields */ }Expand description
A VertexBuffer is a wrapper around an opengl VAO, VBO and EBO.
It is essentially a list of vertices (positions, colors, textures, etc.) and elements (which tell opengl which order to draw/join the vertices in).
You still need to create a [f32] slice of vertex data, which can store
any information you would like to be passed to the shader, and a [u32]
slice telling opengl the order to draw and connect the vertices in.
It shortens the 10+ opengl calls to create the buffers into a single call
of new, as well as many add_component calls as you have components.
In short, this struct allows you to manage the shapes that are drawn to the screen.
Implementations§
Source§impl VertexBuffer
impl VertexBuffer
Sourcepub fn new(vertices: &[f32], elements: &[u32]) -> VertexBuffer
pub fn new(vertices: &[f32], elements: &[u32]) -> VertexBuffer
Create a realms::VertexBuffer with the specified vertices and
elements.
Once created, you need to call the add_component method for each
component of the vertex array to tell the shader where to find each
section of the vertex data (i.e. which parts are positions, colors,
texture coords, etc.).
If you don’t know what opengl vertex buffers are, they are essentially arrays storing information about the triangles to draw to the screen.
Please read https://learnopengl.com/Getting-started/Hello-Triangle (specifically the start of the “Vertex input” section) for more info on opengl indices and buffers.
§Example usage:
§In your rust source file:
let vertices: [f32; 24] = [
// POSITION: COLOR:
0.5, -0.5, 1.0, 0.0, 0.0, 1.0, // bottom right
-0.5, -0.5, 0.0, 1.0, 0.0, 1.0, // bottom left
-0.5, 0.5, 0.0, 0.0, 1.0, 1.0, // top left
0.5, 0.5, 1.0, 1.0, 1.0, 1.0, // top right
];
let elements: [u32; 6] = [
0, 1, 2,
0, 3, 2,
];
let vb: VertexBuffer = VertexBuffer::new(&vertices, &elements);
vb.add_attrib(0, 2, 6, 0);
vb.add_attrib(1, 4, 6, 2);§Then, remember to specify the layouts in the vertex shader:
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec4 aColor;§Panics
Although rare, it is technically possible for this function to PANIC if
the size of the vertices passed in was too large to be converted from a
u32 to an i32. You probably don’t need to worry about this, unless
you have over 2.1 billion vertex components (in which case you’ve got
bigger problems to deal with, such as your GPU being on fire).
Examples found in repository?
12fn main() {
13 let mut window =
14 Window::new(600, 600, "Rendering Pictures?!").expect("Failed to create window");
15
16 let shader_program = ShaderProgram::new(vec![
17 Shader::load_str(ShaderType::Vertex, include_str!("shaders/vertex5.glsl")).unwrap(),
18 Shader::load_str(ShaderType::Fragment, include_str!("shaders/fragment5.glsl")).unwrap(),
19 ])
20 .unwrap();
21
22 let vertices: [f32; 16] = [
23 // specify type `f32` with 16 elements: 4 vertices * 4 floats each.
24 // X Y texX texY
25 -0.5, 0.5, 0.0, 1.0, // top left of triangle, top left of texture
26 -0.5, -0.5, 0.0, 0.0, // bottom left of triangle, bottom left of texture
27 0.5, -0.5, 1.0, 0.0, // bottom right of triangle, bottom right of texture
28 0.5, 0.5, 1.0, 1.0, // top right of triangle, top right of texture
29 ];
30
31 let elements: [u32; 6] = [0, 1, 2, 2, 3, 0];
32
33 let vb = VertexBuffer::new(&vertices, &elements);
34
35 vb.set_layout(&[
36 2, // each vertex has a position, made up of TWO float components (x, y)
37 2, // each vertex has a texture position, made up of TWO float components (x, y)
38 ]);
39
40 let texture = Texture::load_file("examples/images/parrot.png").unwrap();
41 texture.bind();
42
43 while window.is_running() {
44 window.new_frame();
45 window.events();
46
47 window.fill(Color::rgb(39, 85, 163));
48 vb.draw(&shader_program);
49 }
50}More examples
13fn main() {
14 let mut window = Window::new(800, 600, "Hello Colors!").expect("Failed to create window");
15
16 let shader_program = ShaderProgram::new(vec![
17 Shader::load_str(ShaderType::Vertex, include_str!("shaders/vertex3.glsl")).unwrap(),
18 Shader::load_str(ShaderType::Fragment, include_str!("shaders/fragment3.glsl")).unwrap(),
19 ])
20 .unwrap();
21 // NOTE: the shaders have changed slightly since example 2. Please update
22 // `vertex2.glsl` and `fragment2.glsl` using the new versions of them in
23 // this directory.
24
25 let vertices: [f32; 15] = [
26 // specify type `f32` with 15 elements: 3 vertices * 5 floats each.
27 // X Y red green blue
28 0.0, 0.5, 0.0, 1.0, 0.0, // top of triangle, green
29 -0.5, -0.5, 1.0, 0.0, 0.0, // bottom left of triangle, red
30 0.5, -0.5, 0.0, 0.0, 1.0, // bottom right of triangle, blue
31 ];
32
33 // See https://learnopengl.com/Getting-started/Hello-Triangle for more info.
34 // Scroll to the section on Element Buffer Objects.
35 let elements: [u32; 3] = [0, 1, 2];
36
37 let vb = VertexBuffer::new(&vertices, &elements);
38
39 // tell Realms how to split up our vertices array slice:
40 vb.set_layout(&[
41 2, // each vertex has a position, made up of TWO float components (x, y)
42 3, // each vertex has a color, made up of THREE float components (r, g, b)
43 ]);
44
45 while window.is_running() {
46 window.new_frame();
47
48 window.fill(Color::rgb(20, 34, 40));
49 window.events(); // we don't handle any events, but we need to poll for them anyway.
50
51 vb.draw(&shader_program); // draw the data in our vertex buffer
52 }
53}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}9fn main() {
10 // create the window and unwrap the result:
11 let mut window = Window::new(800, 600, "Hello Triangle!").expect("Failed to create window");
12
13 // create the shader program from the shaders `vertex2.glsl` and `fragment2.glsl`:
14 let shader_program = ShaderProgram::new(vec![
15 Shader::load_str(ShaderType::Vertex, include_str!("shaders/vertex2.glsl")).unwrap(),
16 Shader::load_str(ShaderType::Fragment, include_str!("shaders/fragment2.glsl")).unwrap(),
17 ])
18 .unwrap();
19 // NOTE: you need to code the `vertex2.glsl` and `fragment2.glsl` files. Some
20 // default shaders are provided for you, in the same directory as this file
21 // in the files `vertex2.glsl` and `fragment2.glsl`. You can copy and paste
22 // these into the SAME DIRECTORY as your example3_colorful_triangle file.
23
24 // create an [f32] slice of vertex data:
25 let vertices: [f32; 6] = [
26 // specify type `f32` with 6 elements.
27 // X Y
28 0.0, 0.5, // top of triangle
29 -0.5, -0.5, // bottom left of triangle
30 0.5, -0.5, // bottom right of triangle
31 ];
32
33 // Create a [u32] slice listing the indices of the `vertices` array to draw.
34 // Although in this case we only have one triangle, in scenes with many
35 // triangles this drastically reduces the size of data sent to the GPU.
36 // Read more at https://learnopengl.com/Getting-started/Hello-Triangle,
37 // scroll to the section on Element Buffer Objects.
38 let elements: [u32; 3] = [0, 1, 2];
39
40 // create a VertexBuffer using references to the `vertices` and `elements`:
41 let vb = VertexBuffer::new(&vertices, &elements);
42
43 // Tell Realms how each vertex is structured. Each vertex has a single
44 // component (a position) made up of TWO float components (x and y):
45 vb.set_layout(&[2]);
46
47 // loop until the user closes the window
48 while window.is_running() {
49 // swap the buffers (draw to the screen) and bind our shader program:
50 window.new_frame();
51
52 window.fill(Color::rgb(20, 34, 40)); // fill the screen dark blue
53 window.events(); // we don't handle any events, but we need to poll for them anyway.
54
55 vb.draw(&shader_program); // draw the data in our vertex buffer
56 }
57}Sourcepub fn add_attrib(
&self,
layout: u32,
component_count: i32,
stride: i32,
offset: usize,
)
pub fn add_attrib( &self, layout: u32, component_count: i32, stride: i32, offset: usize, )
As the vertices array reference passed to the new function was just
a slice of floats, we need to tell opengl how to split it up.
For each ‘attribute’ of the vertex, call this function. For example, if
you have a vertices array with 4 vertices, and each vertex was made
up of a position (using two floats) and a color (using 4 floats), you
would call the function twice (for each attribute):
let vb = VertexBuffer::new(...);
vb.add_attrib( // position attribute
0, // first attrib, so layout index is 0
2, // the position is made up of 2 floats, so 2 position components
6, // each vertex has 6 floats (2 pos + 4 color) so stride is 6
0, // first attrib, so no offset
)
vb.add_attrib( // color attribute
0, // second attrib, so layout index is 1
4, // the color is made up of 4 floats, so 4 position components
6, // each vertex has 6 floats (2 pos + 4 color) so stride is 6
2, // second attrib. first had 2 components, so offset is 2
)§Panics
It’s likely impossible to occur, but if the value returned by
mem::size_of for the size of a GLfloat cannot be converted into a
GLsizei, the program will PANIC with an expect error.
Sourcepub fn set_layout(&self, component_counts: &[i32])
pub fn set_layout(&self, component_counts: &[i32])
Adding the vertex attributes through the add_attrib method requires a
lot of boilerplate and leads to messy code. Realms can infer all of that
information just from a slice of component counts.
A component count is just a number reflecting the number of floats a
component is made up of. A component is some information about the
vertex that your vertex shader takes in as a layout parameter.
For example, if each vertex has a position and a color, your
component counts may be:
3components for position (X, Y and Z)4components for color (R, G, B and A)- Therefore your
component_countsslice would be[3, 4].
§Example usage
let vb = VertexBuffer::new(...);
vb.set_layout(&[
3, // if our vertex position is made up of 3 floats (x, y, z)
4, // if our vertex color is made up of 4 floats (r, g, b, a)
]);§Panics
If the layout could not be converted from a usize into a u32 (this
could only happen if there are over 4.2 billion components) the program
will PANIC. This will likely never happen.
If the sum of the components are larger than the max usize value, the
program will PANIC. But you will never need that many components.
Also, on 8-bit or 16-bit systems, the max value for a usize is much
lower, so casting each component i32 to a usize may fail and cause
a PANIC.
It’s likely impossible to occur, but if the value returned by
mem::size_of for the size of a GLfloat cannot be converted into a
GLsizei, the program will PANIC with an expect error. This panic is
raised by the add_attrib method.
Examples found in repository?
12fn main() {
13 let mut window =
14 Window::new(600, 600, "Rendering Pictures?!").expect("Failed to create window");
15
16 let shader_program = ShaderProgram::new(vec![
17 Shader::load_str(ShaderType::Vertex, include_str!("shaders/vertex5.glsl")).unwrap(),
18 Shader::load_str(ShaderType::Fragment, include_str!("shaders/fragment5.glsl")).unwrap(),
19 ])
20 .unwrap();
21
22 let vertices: [f32; 16] = [
23 // specify type `f32` with 16 elements: 4 vertices * 4 floats each.
24 // X Y texX texY
25 -0.5, 0.5, 0.0, 1.0, // top left of triangle, top left of texture
26 -0.5, -0.5, 0.0, 0.0, // bottom left of triangle, bottom left of texture
27 0.5, -0.5, 1.0, 0.0, // bottom right of triangle, bottom right of texture
28 0.5, 0.5, 1.0, 1.0, // top right of triangle, top right of texture
29 ];
30
31 let elements: [u32; 6] = [0, 1, 2, 2, 3, 0];
32
33 let vb = VertexBuffer::new(&vertices, &elements);
34
35 vb.set_layout(&[
36 2, // each vertex has a position, made up of TWO float components (x, y)
37 2, // each vertex has a texture position, made up of TWO float components (x, y)
38 ]);
39
40 let texture = Texture::load_file("examples/images/parrot.png").unwrap();
41 texture.bind();
42
43 while window.is_running() {
44 window.new_frame();
45 window.events();
46
47 window.fill(Color::rgb(39, 85, 163));
48 vb.draw(&shader_program);
49 }
50}More examples
13fn main() {
14 let mut window = Window::new(800, 600, "Hello Colors!").expect("Failed to create window");
15
16 let shader_program = ShaderProgram::new(vec![
17 Shader::load_str(ShaderType::Vertex, include_str!("shaders/vertex3.glsl")).unwrap(),
18 Shader::load_str(ShaderType::Fragment, include_str!("shaders/fragment3.glsl")).unwrap(),
19 ])
20 .unwrap();
21 // NOTE: the shaders have changed slightly since example 2. Please update
22 // `vertex2.glsl` and `fragment2.glsl` using the new versions of them in
23 // this directory.
24
25 let vertices: [f32; 15] = [
26 // specify type `f32` with 15 elements: 3 vertices * 5 floats each.
27 // X Y red green blue
28 0.0, 0.5, 0.0, 1.0, 0.0, // top of triangle, green
29 -0.5, -0.5, 1.0, 0.0, 0.0, // bottom left of triangle, red
30 0.5, -0.5, 0.0, 0.0, 1.0, // bottom right of triangle, blue
31 ];
32
33 // See https://learnopengl.com/Getting-started/Hello-Triangle for more info.
34 // Scroll to the section on Element Buffer Objects.
35 let elements: [u32; 3] = [0, 1, 2];
36
37 let vb = VertexBuffer::new(&vertices, &elements);
38
39 // tell Realms how to split up our vertices array slice:
40 vb.set_layout(&[
41 2, // each vertex has a position, made up of TWO float components (x, y)
42 3, // each vertex has a color, made up of THREE float components (r, g, b)
43 ]);
44
45 while window.is_running() {
46 window.new_frame();
47
48 window.fill(Color::rgb(20, 34, 40));
49 window.events(); // we don't handle any events, but we need to poll for them anyway.
50
51 vb.draw(&shader_program); // draw the data in our vertex buffer
52 }
53}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}9fn main() {
10 // create the window and unwrap the result:
11 let mut window = Window::new(800, 600, "Hello Triangle!").expect("Failed to create window");
12
13 // create the shader program from the shaders `vertex2.glsl` and `fragment2.glsl`:
14 let shader_program = ShaderProgram::new(vec![
15 Shader::load_str(ShaderType::Vertex, include_str!("shaders/vertex2.glsl")).unwrap(),
16 Shader::load_str(ShaderType::Fragment, include_str!("shaders/fragment2.glsl")).unwrap(),
17 ])
18 .unwrap();
19 // NOTE: you need to code the `vertex2.glsl` and `fragment2.glsl` files. Some
20 // default shaders are provided for you, in the same directory as this file
21 // in the files `vertex2.glsl` and `fragment2.glsl`. You can copy and paste
22 // these into the SAME DIRECTORY as your example3_colorful_triangle file.
23
24 // create an [f32] slice of vertex data:
25 let vertices: [f32; 6] = [
26 // specify type `f32` with 6 elements.
27 // X Y
28 0.0, 0.5, // top of triangle
29 -0.5, -0.5, // bottom left of triangle
30 0.5, -0.5, // bottom right of triangle
31 ];
32
33 // Create a [u32] slice listing the indices of the `vertices` array to draw.
34 // Although in this case we only have one triangle, in scenes with many
35 // triangles this drastically reduces the size of data sent to the GPU.
36 // Read more at https://learnopengl.com/Getting-started/Hello-Triangle,
37 // scroll to the section on Element Buffer Objects.
38 let elements: [u32; 3] = [0, 1, 2];
39
40 // create a VertexBuffer using references to the `vertices` and `elements`:
41 let vb = VertexBuffer::new(&vertices, &elements);
42
43 // Tell Realms how each vertex is structured. Each vertex has a single
44 // component (a position) made up of TWO float components (x and y):
45 vb.set_layout(&[2]);
46
47 // loop until the user closes the window
48 while window.is_running() {
49 // swap the buffers (draw to the screen) and bind our shader program:
50 window.new_frame();
51
52 window.fill(Color::rgb(20, 34, 40)); // fill the screen dark blue
53 window.events(); // we don't handle any events, but we need to poll for them anyway.
54
55 vb.draw(&shader_program); // draw the data in our vertex buffer
56 }
57}Sourcepub fn draw(&self, shader_program: &ShaderProgram)
pub fn draw(&self, shader_program: &ShaderProgram)
Draw the vertex buffer as a series of triangles.
Note that if you change the elements of the array of vertices or
elements, they will not be updated in the VertexBuffer. If changing
the elements, you should create a new VertexBuffer and call draw on
that instead.
WARNING: This binds the VAO, VBO and EBO. It does not unbind them afterwards.
§Example usage
while w.is_running() {
w.new_frame();
vertex_buffer.draw(&shader_program);
}§Migrating from 2.3.4 to 3.3.4
The Window::new_frame method no longer takes in a shader program
reference, but the VertexBuffer::draw method now does.
You should bind the shader program when calling this draw method, NOT
when calling Window::new_frame.
In short, instead of doing this (pre-3.3.4):
while w.is_running() {
w.new_frame(&shader_program);
vertex_buffer.draw();
}You should do this (3.3.4+):
while w.is_running() {
w.new_frame();
vertex_buffer.draw(&shader_program);
}Examples found in repository?
12fn main() {
13 let mut window =
14 Window::new(600, 600, "Rendering Pictures?!").expect("Failed to create window");
15
16 let shader_program = ShaderProgram::new(vec![
17 Shader::load_str(ShaderType::Vertex, include_str!("shaders/vertex5.glsl")).unwrap(),
18 Shader::load_str(ShaderType::Fragment, include_str!("shaders/fragment5.glsl")).unwrap(),
19 ])
20 .unwrap();
21
22 let vertices: [f32; 16] = [
23 // specify type `f32` with 16 elements: 4 vertices * 4 floats each.
24 // X Y texX texY
25 -0.5, 0.5, 0.0, 1.0, // top left of triangle, top left of texture
26 -0.5, -0.5, 0.0, 0.0, // bottom left of triangle, bottom left of texture
27 0.5, -0.5, 1.0, 0.0, // bottom right of triangle, bottom right of texture
28 0.5, 0.5, 1.0, 1.0, // top right of triangle, top right of texture
29 ];
30
31 let elements: [u32; 6] = [0, 1, 2, 2, 3, 0];
32
33 let vb = VertexBuffer::new(&vertices, &elements);
34
35 vb.set_layout(&[
36 2, // each vertex has a position, made up of TWO float components (x, y)
37 2, // each vertex has a texture position, made up of TWO float components (x, y)
38 ]);
39
40 let texture = Texture::load_file("examples/images/parrot.png").unwrap();
41 texture.bind();
42
43 while window.is_running() {
44 window.new_frame();
45 window.events();
46
47 window.fill(Color::rgb(39, 85, 163));
48 vb.draw(&shader_program);
49 }
50}More examples
13fn main() {
14 let mut window = Window::new(800, 600, "Hello Colors!").expect("Failed to create window");
15
16 let shader_program = ShaderProgram::new(vec![
17 Shader::load_str(ShaderType::Vertex, include_str!("shaders/vertex3.glsl")).unwrap(),
18 Shader::load_str(ShaderType::Fragment, include_str!("shaders/fragment3.glsl")).unwrap(),
19 ])
20 .unwrap();
21 // NOTE: the shaders have changed slightly since example 2. Please update
22 // `vertex2.glsl` and `fragment2.glsl` using the new versions of them in
23 // this directory.
24
25 let vertices: [f32; 15] = [
26 // specify type `f32` with 15 elements: 3 vertices * 5 floats each.
27 // X Y red green blue
28 0.0, 0.5, 0.0, 1.0, 0.0, // top of triangle, green
29 -0.5, -0.5, 1.0, 0.0, 0.0, // bottom left of triangle, red
30 0.5, -0.5, 0.0, 0.0, 1.0, // bottom right of triangle, blue
31 ];
32
33 // See https://learnopengl.com/Getting-started/Hello-Triangle for more info.
34 // Scroll to the section on Element Buffer Objects.
35 let elements: [u32; 3] = [0, 1, 2];
36
37 let vb = VertexBuffer::new(&vertices, &elements);
38
39 // tell Realms how to split up our vertices array slice:
40 vb.set_layout(&[
41 2, // each vertex has a position, made up of TWO float components (x, y)
42 3, // each vertex has a color, made up of THREE float components (r, g, b)
43 ]);
44
45 while window.is_running() {
46 window.new_frame();
47
48 window.fill(Color::rgb(20, 34, 40));
49 window.events(); // we don't handle any events, but we need to poll for them anyway.
50
51 vb.draw(&shader_program); // draw the data in our vertex buffer
52 }
53}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}9fn main() {
10 // create the window and unwrap the result:
11 let mut window = Window::new(800, 600, "Hello Triangle!").expect("Failed to create window");
12
13 // create the shader program from the shaders `vertex2.glsl` and `fragment2.glsl`:
14 let shader_program = ShaderProgram::new(vec![
15 Shader::load_str(ShaderType::Vertex, include_str!("shaders/vertex2.glsl")).unwrap(),
16 Shader::load_str(ShaderType::Fragment, include_str!("shaders/fragment2.glsl")).unwrap(),
17 ])
18 .unwrap();
19 // NOTE: you need to code the `vertex2.glsl` and `fragment2.glsl` files. Some
20 // default shaders are provided for you, in the same directory as this file
21 // in the files `vertex2.glsl` and `fragment2.glsl`. You can copy and paste
22 // these into the SAME DIRECTORY as your example3_colorful_triangle file.
23
24 // create an [f32] slice of vertex data:
25 let vertices: [f32; 6] = [
26 // specify type `f32` with 6 elements.
27 // X Y
28 0.0, 0.5, // top of triangle
29 -0.5, -0.5, // bottom left of triangle
30 0.5, -0.5, // bottom right of triangle
31 ];
32
33 // Create a [u32] slice listing the indices of the `vertices` array to draw.
34 // Although in this case we only have one triangle, in scenes with many
35 // triangles this drastically reduces the size of data sent to the GPU.
36 // Read more at https://learnopengl.com/Getting-started/Hello-Triangle,
37 // scroll to the section on Element Buffer Objects.
38 let elements: [u32; 3] = [0, 1, 2];
39
40 // create a VertexBuffer using references to the `vertices` and `elements`:
41 let vb = VertexBuffer::new(&vertices, &elements);
42
43 // Tell Realms how each vertex is structured. Each vertex has a single
44 // component (a position) made up of TWO float components (x and y):
45 vb.set_layout(&[2]);
46
47 // loop until the user closes the window
48 while window.is_running() {
49 // swap the buffers (draw to the screen) and bind our shader program:
50 window.new_frame();
51
52 window.fill(Color::rgb(20, 34, 40)); // fill the screen dark blue
53 window.events(); // we don't handle any events, but we need to poll for them anyway.
54
55 vb.draw(&shader_program); // draw the data in our vertex buffer
56 }
57}