use std::slice;
use std::mem;
pub enum UniformPrimitiveType {
Float,
Int
}
pub enum UniformDatumType {
Vec1(UniformPrimitiveType),
Vec2(UniformPrimitiveType),
Vec3(UniformPrimitiveType),
Vec4(UniformPrimitiveType),
Matrix2x2,
Matrix3x3,
Matrix4x4
}
pub trait UniformData {
fn uniform_datum_type() -> UniformDatumType;
fn uniform_bytes(&self) -> &[u8];
fn uniform_elements(&self) -> usize;
}
pub unsafe trait UniformDatum {
fn uniform_datum_type() -> UniformDatumType;
}
pub unsafe trait UniformPrimitive {
fn uniform_primitive_type() -> UniformPrimitiveType;
}
unsafe impl UniformPrimitive for f32 {
fn uniform_primitive_type() -> UniformPrimitiveType {
UniformPrimitiveType::Float
}
}
unsafe impl UniformPrimitive for i32 {
fn uniform_primitive_type() -> UniformPrimitiveType {
UniformPrimitiveType::Int
}
}
unsafe impl<T: UniformPrimitive> UniformDatum for T {
fn uniform_datum_type() -> UniformDatumType {
UniformDatumType::Vec1(T::uniform_primitive_type())
}
}
unsafe impl<T: UniformPrimitive> UniformDatum for [T; 1] {
fn uniform_datum_type() -> UniformDatumType {
UniformDatumType::Vec1(T::uniform_primitive_type())
}
}
unsafe impl<T: UniformPrimitive> UniformDatum for [T; 2] {
fn uniform_datum_type() -> UniformDatumType {
UniformDatumType::Vec1(T::uniform_primitive_type())
}
}
unsafe impl<T: UniformPrimitive> UniformDatum for [T; 3] {
fn uniform_datum_type() -> UniformDatumType {
UniformDatumType::Vec1(T::uniform_primitive_type())
}
}
unsafe impl<T> UniformDatum for [T; 4] where T: UniformPrimitive {
fn uniform_datum_type() -> UniformDatumType {
UniformDatumType::Vec1(T::uniform_primitive_type())
}
}
unsafe impl UniformDatum for [[f32; 2]; 2] {
fn uniform_datum_type() -> UniformDatumType {
UniformDatumType::Matrix2x2
}
}
unsafe impl UniformDatum for [[f32; 3]; 3] {
fn uniform_datum_type() -> UniformDatumType {
UniformDatumType::Matrix3x3
}
}
unsafe impl UniformDatum for [[f32; 4]; 4] {
fn uniform_datum_type() -> UniformDatumType {
UniformDatumType::Matrix4x4
}
}
impl<T: UniformDatum> UniformData for T {
fn uniform_datum_type() -> UniformDatumType {
T::uniform_datum_type()
}
fn uniform_bytes(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(mem::transmute(self), mem::size_of::<T>())
}
}
fn uniform_elements(&self) -> usize {
1
}
}
impl<T: UniformDatum> UniformData for [T] {
fn uniform_datum_type() -> UniformDatumType {
T::uniform_datum_type()
}
fn uniform_bytes(&self) -> &[u8] {
let size = mem::size_of::<T>() * self.len();
unsafe {
slice::from_raw_parts(mem::transmute(&self[0]), size)
}
}
fn uniform_elements(&self) -> usize {
self.len()
}
}