renderling 0.4.9

User-friendly real-time rendering. 🍖
Documentation
//! Sometimes you just need a mesh.
use wgpu::util::DeviceExt;

/// A vertex buffer.
pub struct Mesh {
    vertex_buffer: wgpu::Buffer,
    vertex_buffer_len: usize,
    vertex_indices: Option<(wgpu::Buffer, usize)>,
}

impl Mesh {
    pub fn new<V: bytemuck::Pod>(
        device: &wgpu::Device,
        label: Option<&str>,
        vertices: impl IntoIterator<Item = V>,
        may_indices: Option<impl IntoIterator<Item = u16>>,
    ) -> Self {
        let vertices = vertices.into_iter().collect::<Vec<_>>();
        let vertex_buffer_len = vertices.len();
        let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
            label,
            contents: bytemuck::cast_slice(&vertices),
            usage: wgpu::BufferUsages::VERTEX,
        });
        let vertex_indices = if let Some(indices) = may_indices {
            let indices = indices.into_iter().collect::<Vec<_>>();
            let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
                label,
                contents: bytemuck::cast_slice(&indices),
                usage: wgpu::BufferUsages::INDEX,
            });
            Some((index_buffer, indices.len()))
        } else {
            None
        };
        Self {
            vertex_buffer,
            vertex_buffer_len,
            vertex_indices,
        }
    }

    pub fn from_vertices<V: bytemuck::Pod>(
        device: &wgpu::Device,
        label: Option<&str>,
        vertices: impl IntoIterator<Item = V>,
    ) -> Self {
        Self::new(device, label, vertices, None as Option<Vec<u16>>)
    }

    pub fn draw<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) {
        render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
        match &self.vertex_indices {
            Some((index_buffer, len)) => {
                render_pass.set_index_buffer(index_buffer.slice(..), wgpu::IndexFormat::Uint16);
                render_pass.draw_indexed(0..*len as u32, 0, 0..1);
            }
            None => {
                render_pass.draw(0..self.vertex_buffer_len as u32, 0..1);
            }
        }
    }

    pub fn update<V: bytemuck::Pod>(
        &mut self,
        device: &wgpu::Device,
        label: Option<&str>,
        vertices: impl IntoIterator<Item = V>,
        may_indices: Option<impl IntoIterator<Item = u16>>,
    ) {
        let vertices = vertices.into_iter().collect::<Vec<_>>();
        self.vertex_buffer_len = vertices.len();
        self.vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
            label,
            contents: bytemuck::cast_slice(&vertices),
            usage: wgpu::BufferUsages::VERTEX,
        });
        self.vertex_indices = if let Some(indices) = may_indices {
            let indices = indices.into_iter().collect::<Vec<_>>();
            let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
                label,
                contents: bytemuck::cast_slice(&indices),
                usage: wgpu::BufferUsages::INDEX,
            });
            Some((buffer, indices.len()))
        } else {
            None
        };
    }
}