Skip to main content

VertexBuffer

Struct VertexBuffer 

Source
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

Source

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?
examples/example_5_texture.rs (line 33)
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
Hide additional examples
examples/example_3_colorful_triangle.rs (line 37)
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}
examples/example_4_2d_camera.rs (line 39)
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}
examples/example_2_triangle.rs (line 41)
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}
Source

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.

Source

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:

  • 3 components for position (X, Y and Z)
  • 4 components for color (R, G, B and A)
  • Therefore your component_counts slice 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?
examples/example_5_texture.rs (lines 35-38)
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
Hide additional examples
examples/example_3_colorful_triangle.rs (lines 40-43)
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}
examples/example_4_2d_camera.rs (line 42)
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}
examples/example_2_triangle.rs (line 45)
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}
Source

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?
examples/example_5_texture.rs (line 48)
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
Hide additional examples
examples/example_3_colorful_triangle.rs (line 51)
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}
examples/example_4_2d_camera.rs (line 67)
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}
examples/example_2_triangle.rs (line 55)
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}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.