rust-gl 0.1.7

Rust wrapper around webgl.
use super::GL;
use std::rc::Rc;
pub struct Target<C, const N: u32>(pub Rc<C>);

use core::ops::Deref;
impl<C, const N: u32> Deref for Target<C, N> {
    type Target = C;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

pub struct TextureTarget<C, const N: u32>(Rc<C>);
impl<C, const N: u32> Deref for TextureTarget<C, N> {
    type Target = C;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

pub struct Context {
    pub gl: Rc<GL>,
    pub array_buffer: Target<GL, { GL::ARRAY_BUFFER }>,
    pub copy_read_buffer: Target<GL, { GL::COPY_READ_BUFFER }>,
    pub copy_write_buffer: Target<GL, { GL::COPY_WRITE_BUFFER }>,
    pub element_array_buffer: Target<GL, { GL::ELEMENT_ARRAY_BUFFER }>,
    pub pixel_pack_buffer: Target<GL, { GL::PIXEL_PACK_BUFFER }>,
    pub pixel_unpack_buffer: Target<GL, { GL::PIXEL_UNPACK_BUFFER }>,
    pub transform_feedback_buffer: Target<GL, { GL::TRANSFORM_FEEDBACK_BUFFER }>,
    pub uniform_buffer: Target<GL, { GL::UNIFORM_BUFFER }>,
    pub texture_2d: TextureTarget<GL, { GL::TEXTURE_2D }>,
    pub texture_cube_map: TextureTarget<GL, { GL::TEXTURE_CUBE_MAP }>,
    pub texture_3d: TextureTarget<GL, { GL::TEXTURE_3D }>,
    pub texture_2d_array: TextureTarget<GL, { GL::TEXTURE_3D }>,
}
impl Deref for Context {
    type Target = GL;
    fn deref(&self) -> &Self::Target {
        &self.gl
    }
}
impl From<GL> for Context {
    fn from(gl: GL) -> Context {
        let rc = Rc::new(gl);
        Self {
            gl: rc.clone(),
            array_buffer: Target(rc.clone()),
            copy_read_buffer: Target(rc.clone()),
            copy_write_buffer: Target(rc.clone()),
            element_array_buffer: Target(rc.clone()),
            pixel_pack_buffer: Target(rc.clone()),
            pixel_unpack_buffer: Target(rc.clone()),
            transform_feedback_buffer: Target(rc.clone()),
            uniform_buffer: Target(rc.clone()),
            texture_2d: TextureTarget(rc.clone()),
            texture_cube_map: TextureTarget(rc.clone()),
            texture_3d: TextureTarget(rc.clone()),
            texture_2d_array: TextureTarget(rc.clone()),
        }
    }
}

///Internal errors from opengl.
#[derive(Debug, PartialEq, Eq)]
pub enum Error {
    InvalidEnum,
    InvalidValue,
    InvalidOperation,
    InvalidFramebufferOperation,
    OutOfMemory,
    ContextLost,
}

use core::fmt;
impl fmt::Display for Error {
    fn fmt(&self, format: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
        write! {format, "{:?}", self}
    }
}

impl std::error::Error for Error {}

pub trait GLError {
    type Error;
    fn error(&self) -> Result<(), Self::Error>;
}

impl GLError for GL {
    type Error = Error;
    ///Retrive the current opengl error, if there is no error Ok(()) is returned.
    fn error(&self) -> Result<(), Error> {
        match self.get_error() {
            GL::INVALID_ENUM => Err(Error::InvalidEnum),
            GL::INVALID_VALUE => Err(Error::InvalidValue),
            GL::INVALID_OPERATION => Err(Error::InvalidOperation),
            GL::INVALID_FRAMEBUFFER_OPERATION => Err(Error::InvalidFramebufferOperation),
            GL::OUT_OF_MEMORY => Err(Error::OutOfMemory),
            GL::CONTEXT_LOST_WEBGL => Err(Error::ContextLost),
            _ => Ok(()),
        }
    }
}
use super::attribute::GLType;
use core::ops::Range;
impl Context {
    //Rust like version of the opengl draw_arrays function
    pub fn draw_arrays(&mut self, mode: u32, range: Range<i32>) {
        self.gl
            .draw_arrays(mode, range.start, range.end - range.start);
    }
    //Rust like version of the opengl draw_elements function
    pub fn draw_elements<T>(&mut self, mode: u32, range: Range<i32>)
    where
        T: GLType,
    {
        use std::mem::size_of;
        self.gl.draw_elements_with_i32(
            mode,
            range.end - range.start,
            T::TYPE,
            range.start * size_of::<T>() as i32,
        );
    }
}