picodraw 0.2.0

A smol gpu graphics library
Documentation
use crate::*;
use std::{array::from_fn, sync::Arc};

pub trait ShaderData {
    type ShaderVars;

    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars;
    fn write(&self, writer: &mut dyn ShaderDataWriter);
}

pub trait ShaderVars {
    fn read_int8(&mut self) -> Int;
    fn read_int16(&mut self) -> Int;
    fn read_int32(&mut self) -> Int;
    fn read_uint8(&mut self) -> Int;
    fn read_uint16(&mut self) -> Int;
    fn read_uint32(&mut self) -> Int;
    fn read_float(&mut self) -> Float;
    fn texture(&mut self, tex: Arc<dyn Fn() -> image::DynamicImage>) -> Texture;
    fn resolution(&mut self) -> Float2;
}

pub trait ShaderDataWriter {
    fn resolution(&self) -> (f32, f32);
    fn write_float(&mut self, x: f32);
    fn write_int(&mut self, x: i32);
}

impl ShaderData for () {
    type ShaderVars = ();
    fn shader_vars(_vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        ()
    }
    fn write(&self, _writer: &mut dyn ShaderDataWriter) {}
}

impl ShaderData for bool {
    type ShaderVars = Bool;
    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        vars.read_uint8().neq(0)
    }
    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        writer.write_int(if *self { 1 } else { 0 })
    }
}

impl ShaderData for u8 {
    type ShaderVars = Int;
    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        vars.read_uint8()
    }
    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        writer.write_int(*self as i32)
    }
}

impl ShaderData for u16 {
    type ShaderVars = Int;
    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        vars.read_uint16()
    }
    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        writer.write_int(*self as i32)
    }
}

impl ShaderData for u32 {
    type ShaderVars = Int;
    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        vars.read_uint32()
    }
    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        writer.write_int(*self as i32)
    }
}

impl ShaderData for i8 {
    type ShaderVars = Int;
    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        vars.read_int8()
    }
    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        writer.write_int(*self as i32)
    }
}

impl ShaderData for i16 {
    type ShaderVars = Int;
    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        vars.read_int16()
    }
    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        writer.write_int(*self as i32)
    }
}

impl ShaderData for i32 {
    type ShaderVars = Int;
    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        vars.read_int32()
    }
    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        writer.write_int(*self as i32)
    }
}

impl ShaderData for f32 {
    type ShaderVars = Float;
    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        vars.read_float()
    }
    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        writer.write_float(*self)
    }
}

impl ShaderData for f64 {
    type ShaderVars = Float;
    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        vars.read_float()
    }
    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        writer.write_float(*self as f32)
    }
}

impl<const N: usize, T: ShaderData> ShaderData for [T; N] {
    type ShaderVars = [T::ShaderVars; N];

    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        from_fn(|_| T::shader_vars(vars))
    }

    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        for i in 0..N {
            self[i].write(writer);
        }
    }
}

impl<'a, T: ShaderData> ShaderData for &'a T {
    type ShaderVars = T::ShaderVars;
    fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
        T::shader_vars(vars)
    }
    fn write(&self, writer: &mut dyn ShaderDataWriter) {
        T::write(&self, writer)
    }
}

macro_rules! impl_tuple {
    ($($id:ident),*) => {
        impl<$($id: ShaderData),*> ShaderData for ($($id,)*) {
            type ShaderVars = ($($id::ShaderVars,)*);

            fn shader_vars(vars: &mut dyn ShaderVars) -> Self::ShaderVars {
                ($($id::shader_vars(vars),)*)
            }

            fn write(&self, writer: &mut dyn ShaderDataWriter) {
                #[allow(non_snake_case)]
                let ($($id,)*) = self;
                $($id::write($id, writer);)*
            }
        }
    };
}

impl_tuple!(A);
impl_tuple!(A, B);
impl_tuple!(A, B, C);
impl_tuple!(A, B, C, D);
impl_tuple!(A, B, C, D, E);
impl_tuple!(A, B, C, D, E, F);