use gl;
use gl::types::*;
pub unsafe trait Pixel {
type Encoding;
type RawEncoding;
fn pixel_format() -> PixelFormat;
}
pub unsafe trait ColorPixel: Pixel {}
pub unsafe trait DepthPixel: Pixel {}
pub unsafe trait RenderablePixel: Pixel {}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct PixelFormat {
pub encoding: Type,
pub format: Format
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Type {
Integral,
Unsigned,
Floating
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Format {
R(Size),
RG(Size, Size),
RGB(Size, Size, Size),
RGBA(Size, Size, Size, Size),
Depth(Size)
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Size {
Eight,
Sixteen,
ThirtyTwo
}
pub fn is_color_pixel(f: PixelFormat) -> bool {
match f.format {
Format::Depth(_) => false,
_ => true
}
}
pub fn is_depth_pixel(f: PixelFormat) -> bool {
!is_color_pixel(f)
}
macro_rules! impl_Pixel {
($t:ty, $encoding:ty, $raw_encoding:ty, $encoding_ty:expr, $format:expr) => {
unsafe impl Pixel for $t {
type Encoding = $encoding;
type RawEncoding = $raw_encoding;
fn pixel_format() -> PixelFormat {
PixelFormat {
encoding: $encoding_ty,
format: $format
}
}
}
}
}
macro_rules! impl_ColorPixel {
($t:ty) => {
unsafe impl ColorPixel for $t {}
}
}
macro_rules! impl_DepthPixel {
($t:ty) => {
unsafe impl DepthPixel for $t {}
}
}
macro_rules! impl_RenderablePixel {
($t:ty) => {
unsafe impl RenderablePixel for $t {}
}
}
#[derive(Clone, Copy, Debug)]
pub struct R8I;
impl_Pixel!(R8I, i8, i8, Type::Integral, Format::R(Size::Eight));
impl_ColorPixel!(R8I);
impl_RenderablePixel!(R8I);
#[derive(Clone, Copy, Debug)]
pub struct R8UI;
impl_Pixel!(R8UI, u8, u8, Type::Unsigned, Format::R(Size::Eight));
impl_ColorPixel!(R8UI);
impl_RenderablePixel!(R8UI);
#[derive(Clone, Copy, Debug)]
pub struct R16I;
impl_Pixel!(R16I, i16, i16, Type::Integral, Format::R(Size::Sixteen));
impl_ColorPixel!(R16I);
impl_RenderablePixel!(R16I);
#[derive(Clone, Copy, Debug)]
pub struct R16UI;
impl_Pixel!(R16UI, u16, u16, Type::Unsigned, Format::R(Size::Sixteen));
impl_ColorPixel!(R16UI);
impl_RenderablePixel!(R16UI);
#[derive(Clone, Copy, Debug)]
pub struct R32I;
impl_Pixel!(R32I, i32, i32, Type::Integral, Format::R(Size::ThirtyTwo));
impl_ColorPixel!(R32I);
impl_RenderablePixel!(R32I);
#[derive(Clone, Copy, Debug)]
pub struct R32UI;
impl_Pixel!(R32UI, u32, u32, Type::Unsigned, Format::R(Size::ThirtyTwo));
impl_ColorPixel!(R32UI);
impl_RenderablePixel!(R32UI);
#[derive(Clone, Copy, Debug)]
pub struct R32F;
impl_Pixel!(R32F, f32, f32, Type::Floating, Format::R(Size::ThirtyTwo));
impl_ColorPixel!(R32F);
impl_RenderablePixel!(R32F);
#[derive(Clone, Copy, Debug)]
pub struct RG8I;
impl_Pixel!(RG8I, (i8, i8), i8, Type::Integral, Format::RG(Size::Eight, Size::Eight));
impl_ColorPixel!(RG8I);
impl_RenderablePixel!(RG8I);
#[derive(Clone, Copy, Debug)]
pub struct RG8UI;
impl_Pixel!(RG8UI, (u8, u8), u8, Type::Unsigned, Format::RG(Size::Eight, Size::Eight));
impl_ColorPixel!(RG8UI);
impl_RenderablePixel!(RG8UI);
#[derive(Clone, Copy, Debug)]
pub struct RG16I;
impl_Pixel!(RG16I, (i16, i16), i16, Type::Integral, Format::RG(Size::Sixteen, Size::Sixteen));
impl_ColorPixel!(RG16I);
impl_RenderablePixel!(RG16I);
#[derive(Clone, Copy, Debug)]
pub struct RG16UI;
impl_Pixel!(RG16UI, (u16, u16), u16, Type::Unsigned, Format::RG(Size::Sixteen, Size::Sixteen));
impl_ColorPixel!(RG16UI);
impl_RenderablePixel!(RG16UI);
#[derive(Clone, Copy, Debug)]
pub struct RG32I;
impl_Pixel!(RG32I, (i32, i32), i32, Type::Integral, Format::RG(Size::ThirtyTwo, Size::ThirtyTwo));
impl_ColorPixel!(RG32I);
impl_RenderablePixel!(RG32I);
#[derive(Clone, Copy, Debug)]
pub struct RG32UI;
impl_Pixel!(RG32UI, (u32, u32), u32, Type::Unsigned, Format::RG(Size::ThirtyTwo, Size::ThirtyTwo));
impl_ColorPixel!(RG32UI);
impl_RenderablePixel!(RG32UI);
#[derive(Clone, Copy, Debug)]
pub struct RG32F;
impl_Pixel!(RG32F, (f32, f32), f32, Type::Floating, Format::RG(Size::ThirtyTwo, Size::ThirtyTwo));
impl_ColorPixel!(RG32F);
impl_RenderablePixel!(RG32F);
#[derive(Clone, Copy, Debug)]
pub struct RGB8I;
impl_Pixel!(RGB8I, (i8, i8, i8), i8, Type::Integral, Format::RGB(Size::Eight, Size::Eight, Size::Eight));
impl_ColorPixel!(RGB8I);
impl_RenderablePixel!(RGB8I);
#[derive(Clone, Copy, Debug)]
pub struct RGB8UI;
impl_Pixel!(RGB8UI, (u8, u8, u8), u8, Type::Unsigned, Format::RGB(Size::Eight, Size::Eight, Size::Eight));
impl_ColorPixel!(RGB8UI);
impl_RenderablePixel!(RGB8UI);
#[derive(Clone, Copy, Debug)]
pub struct RGB16I;
impl_Pixel!(RGB16I, (i16, i16, i16), i16, Type::Integral, Format::RGB(Size::Sixteen, Size::Sixteen, Size::Sixteen));
impl_ColorPixel!(RGB16I);
impl_RenderablePixel!(RGB16I);
#[derive(Clone, Copy, Debug)]
pub struct RGB16UI;
impl_Pixel!(RGB16UI, (u16, u16, u16), u16, Type::Unsigned, Format::RGB(Size::Sixteen, Size::Sixteen, Size::Sixteen));
impl_ColorPixel!(RGB16UI);
impl_RenderablePixel!(RGB16UI);
#[derive(Clone, Copy, Debug)]
pub struct RGB32I;
impl_Pixel!(RGB32I, (i32, i32, i32), i32, Type::Integral, Format::RGB(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo));
impl_ColorPixel!(RGB32I);
impl_RenderablePixel!(RGB32I);
#[derive(Clone, Copy, Debug)]
pub struct RGB32UI;
impl_Pixel!(RGB32UI, (u32, u32, u32), u32, Type::Unsigned, Format::RGB(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo));
impl_ColorPixel!(RGB32UI);
impl_RenderablePixel!(RGB32UI);
#[derive(Clone, Copy, Debug)]
pub struct RGB32F;
impl_Pixel!(RGB32F, (f32, f32, f32), f32, Type::Floating, Format::RGB(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo));
impl_ColorPixel!(RGB32F);
impl_RenderablePixel!(RGB32F);
#[derive(Clone, Copy, Debug)]
pub struct RGBA8I;
impl_Pixel!(RGBA8I, (i8, i8, i8, i8), i8, Type::Integral, Format::RGBA(Size::Eight, Size::Eight, Size::Eight, Size::Eight));
impl_ColorPixel!(RGBA8I);
impl_RenderablePixel!(RGBA8I);
#[derive(Clone, Copy, Debug)]
pub struct RGBA8UI;
impl_Pixel!(RGBA8UI, (u8, u8, u8, u8), u8, Type::Unsigned, Format::RGBA(Size::Eight, Size::Eight, Size::Eight, Size::Eight));
impl_ColorPixel!(RGBA8UI);
impl_RenderablePixel!(RGBA8UI);
#[derive(Clone, Copy, Debug)]
pub struct RGBA16I;
impl_Pixel!(RGBA16I, (i16, i16, i16, i16), i16, Type::Integral, Format::RGBA(Size::Sixteen, Size::Sixteen, Size::Sixteen, Size::Sixteen));
impl_ColorPixel!(RGBA16I);
impl_RenderablePixel!(RGBA16I);
#[derive(Clone, Copy, Debug)]
pub struct RGBA16UI;
impl_Pixel!(RGBA16UI, (u16, u16, u16, u16), u16, Type::Unsigned, Format::RGBA(Size::Sixteen, Size::Sixteen, Size::Sixteen, Size::Sixteen));
impl_ColorPixel!(RGBA16UI);
impl_RenderablePixel!(RGBA16UI);
#[derive(Clone, Copy, Debug)]
pub struct RGBA32I;
impl_Pixel!(RGBA32I, (i32, i32, i32, i32), i32, Type::Integral, Format::RGBA(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo));
impl_ColorPixel!(RGBA32I);
impl_RenderablePixel!(RGBA32I);
#[derive(Clone, Copy, Debug)]
pub struct RGBA32UI;
impl_Pixel!(RGBA32UI, (u32, u32, u32, u32), u32, Type::Unsigned, Format::RGBA(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo));
impl_ColorPixel!(RGBA32UI);
impl_RenderablePixel!(RGBA32UI);
#[derive(Clone, Copy, Debug)]
pub struct RGBA32F;
impl_Pixel!(RGBA32F, (f32, f32, f32, f32), f32, Type::Floating, Format::RGBA(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo));
impl_ColorPixel!(RGBA32F);
impl_RenderablePixel!(RGBA32F);
#[derive(Clone, Copy, Debug)]
pub struct Depth32F;
impl_Pixel!(Depth32F, f32, f32, Type::Floating, Format::Depth(Size::ThirtyTwo));
impl_DepthPixel!(Depth32F);
pub(crate) fn opengl_pixel_format(pf: PixelFormat) -> Option<(GLenum, GLenum, GLenum)> {
match (pf.format, pf.encoding) {
(Format::R(Size::Eight), Type::Integral) => Some((gl::RED_INTEGER, gl::R8I, gl::BYTE)),
(Format::R(Size::Eight), Type::Unsigned) => Some((gl::RED_INTEGER, gl::R8UI, gl::UNSIGNED_BYTE)),
(Format::R(Size::Sixteen), Type::Integral) => Some((gl::RED_INTEGER, gl::R16I, gl::SHORT)),
(Format::R(Size::Sixteen), Type::Unsigned) => Some((gl::RED_INTEGER, gl::R16UI, gl::UNSIGNED_SHORT)),
(Format::R(Size::ThirtyTwo), Type::Integral) => Some((gl::RED_INTEGER, gl::R32I, gl::INT)),
(Format::R(Size::ThirtyTwo), Type::Unsigned) => Some((gl::RED_INTEGER, gl::R32UI, gl::UNSIGNED_INT)),
(Format::R(Size::ThirtyTwo), Type::Floating) => Some((gl::RED, gl::R32F, gl::FLOAT)),
(Format::RG(Size::Eight, Size::Eight), Type::Integral) => Some((gl::RG_INTEGER, gl::RG8I, gl::BYTE)),
(Format::RG(Size::Eight, Size::Eight), Type::Unsigned) => Some((gl::RG_INTEGER, gl::RG8UI, gl::UNSIGNED_BYTE)),
(Format::RG(Size::Sixteen, Size::Sixteen), Type::Integral) => Some((gl::RG_INTEGER, gl::RG16I, gl::SHORT)),
(Format::RG(Size::Sixteen, Size::Sixteen), Type::Unsigned) => Some((gl::RG_INTEGER, gl::RG16UI, gl::UNSIGNED_SHORT)),
(Format::RG(Size::ThirtyTwo, Size::ThirtyTwo), Type::Integral) => Some((gl::RG_INTEGER, gl::RG32I, gl::INT)),
(Format::RG(Size::ThirtyTwo, Size::ThirtyTwo), Type::Unsigned) => Some((gl::RG_INTEGER, gl::RG32UI, gl::UNSIGNED_INT)),
(Format::RG(Size::ThirtyTwo, Size::ThirtyTwo), Type::Floating) => Some((gl::RG, gl::RG32F, gl::FLOAT)),
(Format::RGB(Size::Eight, Size::Eight, Size::Eight), Type::Integral) => Some((gl::RGB_INTEGER, gl::RGB8I, gl::BYTE)),
(Format::RGB(Size::Eight, Size::Eight, Size::Eight), Type::Unsigned) => Some((gl::RGB_INTEGER, gl::RGB8UI, gl::UNSIGNED_BYTE)),
(Format::RGB(Size::Sixteen, Size::Sixteen, Size::Sixteen), Type::Integral) => Some((gl::RGB_INTEGER, gl::RGB16I, gl::SHORT)),
(Format::RGB(Size::Sixteen, Size::Sixteen, Size::Sixteen), Type::Unsigned) => Some((gl::RGB_INTEGER, gl::RGB16UI, gl::UNSIGNED_SHORT)),
(Format::RGB(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo), Type::Integral) => Some((gl::RGB_INTEGER, gl::RGB32I, gl::INT)),
(Format::RGB(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo), Type::Unsigned) => Some((gl::RGB_INTEGER, gl::RGB32UI, gl::UNSIGNED_INT)),
(Format::RGB(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo), Type::Floating) => Some((gl::RGB, gl::RGB32F, gl::FLOAT)),
(Format::RGBA(Size::Eight, Size::Eight, Size::Eight, Size::Eight), Type::Integral) => Some((gl::RGBA_INTEGER, gl::RGBA8I, gl::BYTE)),
(Format::RGBA(Size::Eight, Size::Eight, Size::Eight, Size::Eight), Type::Unsigned) => Some((gl::RGBA_INTEGER, gl::RGBA8UI, gl::UNSIGNED_BYTE)),
(Format::RGBA(Size::Sixteen, Size::Sixteen, Size::Sixteen, Size::Sixteen), Type::Integral) => Some((gl::RGBA_INTEGER, gl::RGBA16I, gl::SHORT)),
(Format::RGBA(Size::Sixteen, Size::Sixteen, Size::Sixteen, Size::Sixteen), Type::Unsigned) => Some((gl::RGBA_INTEGER, gl::RGBA16UI, gl::UNSIGNED_SHORT)),
(Format::RGBA(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo), Type::Integral) => Some((gl::RGBA_INTEGER, gl::RGBA32I, gl::INT)),
(Format::RGBA(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo), Type::Unsigned) => Some((gl::RGBA_INTEGER, gl::RGBA32UI, gl::UNSIGNED_INT)),
(Format::RGBA(Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo, Size::ThirtyTwo), Type::Floating) => Some((gl::RGBA, gl::RGBA32F, gl::FLOAT)),
(Format::Depth(Size::ThirtyTwo), Type::Floating) => Some((gl::DEPTH_COMPONENT, gl::DEPTH_COMPONENT32F, gl::FLOAT)),
_ => panic!("unsupported pixel format {:?}", pf)
}
}
pub(crate) fn pixel_components(pf: PixelFormat) -> usize {
match pf.format {
Format::RGB(_, _, _) => 3,
Format::RGBA(_, _, _, _) => 4,
Format::Depth(_) => 1,
_ => panic!("unsupported pixel format")
}
}