inochi2d 0.1.1

Pure Rust implementation of Inochi2D, the realtime 2D puppet animation framework
Documentation
use glow::HasContext;

pub enum Vbo<'a, T: Copy> {
    Buffering(&'a glow::Context, Vec<T>),
    Uploaded(glow::NativeBuffer),
}

impl<'a, T: Copy> Vbo<'a, T> {
    pub fn new(gl: &'a glow::Context) -> Vbo<'a, T> {
        Vbo::Buffering(gl, Vec::new())
    }

    pub fn from(gl: &'a glow::Context, vec: Vec<T>) -> Vbo<'a, T> {
        Vbo::Buffering(gl, vec)
    }

    pub fn len(&self) -> usize {
        match self {
            Vbo::Buffering(_, vec) => vec.len(),
            _ => panic!("Vbo must not be uploaded yet!"),
        }
    }

    pub fn extend_from_slice(&mut self, other: &[T]) {
        match self {
            Vbo::Buffering(_, vec) => vec.extend_from_slice(other),
            _ => panic!("Vbo must not be uploaded yet!"),
        }
    }

    pub fn extend<I: IntoIterator<Item = T>>(&mut self, other: I) {
        match self {
            Vbo::Buffering(_, vec) => vec.extend(other),
            _ => panic!("Vbo must not be uploaded yet!"),
        }
    }

    pub unsafe fn upload(&mut self, target: u32, usage: u32) {
        match self {
            Vbo::Buffering(gl, vec) => {
                let slice = &vec;
                let bytes: &[u8] = core::slice::from_raw_parts(
                    slice.as_ptr() as *const u8,
                    slice.len() * core::mem::size_of::<T>(),
                );
                let vbo = gl.create_buffer().unwrap();
                gl.bind_buffer(target, Some(vbo));
                gl.buffer_data_u8_slice(target, bytes, usage);
                *self = Vbo::Uploaded(vbo);
            }
            _ => panic!("Vbo must not be uploaded yet!"),
        }
    }
}