dunge 0.3.0-alpha

Simple and portable 3d render library
Documentation
use crate::{
    sl::{GlobalOut, ReadGlobal, Ret},
    texture::{BindTexture, Sampler, Texture},
    types::{self, MemberType},
    uniform::{Uniform, Value},
};

pub use dunge_shader::group::{DeclareGroup, Projection};

#[derive(Clone, Copy)]
pub struct BoundTexture<'a>(&'a Texture);

impl<'a> BoundTexture<'a> {
    pub fn new<T>(texture: &'a T) -> Self
    where
        T: BindTexture,
    {
        Self(texture.bind_texture())
    }

    pub(crate) fn get(self) -> &'a Texture {
        self.0
    }
}

/// Describes a group member type projection.
///
/// The trait is sealed because the derive macro relies on no new types being used.
pub trait MemberProjection: private::Sealed {
    const TYPE: MemberType;
    type Field;
    fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field;
}

impl<V> private::Sealed for &Uniform<V> where V: Value {}

impl<V> MemberProjection for &Uniform<V>
where
    V: Value,
{
    const TYPE: MemberType = V::TYPE;
    type Field = Ret<ReadGlobal, V::Type>;

    fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field {
        ReadGlobal::new(id, binding, Self::TYPE.is_value(), out)
    }
}

impl private::Sealed for BoundTexture<'_> {}

impl MemberProjection for BoundTexture<'_> {
    const TYPE: MemberType = MemberType::Tx2df;
    type Field = Ret<ReadGlobal, types::Texture2d<f32>>;

    fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field {
        ReadGlobal::new(id, binding, Self::TYPE.is_value(), out)
    }
}

impl private::Sealed for &Sampler {}

impl MemberProjection for &Sampler {
    const TYPE: MemberType = MemberType::Sampl;
    type Field = Ret<ReadGlobal, types::Sampler>;

    fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field {
        ReadGlobal::new(id, binding, Self::TYPE.is_value(), out)
    }
}

mod private {
    pub trait Sealed {}
}