use attrib::{FloatSize, IntSubType};
use std::default::Default;
use std::fmt;
use state;
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum SurfaceError {
UnsupportedFormat,
UnsupportedGamma,
}
#[derive(Copy, Clone, PartialEq)]
pub enum TextureError {
UnsupportedFormat,
UnsupportedGamma,
UnsupportedSampling,
InvalidInfo(TextureInfo),
IncorrectSize(usize),
}
impl fmt::Debug for TextureError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&TextureError::UnsupportedFormat =>
write!(f, "Failed to map a given format to the device"),
&TextureError::UnsupportedGamma =>
write!(f, "Failed to provide sRGB formats"),
&TextureError::UnsupportedSampling =>
write!(
f,
"Failed to map a given multisampled kind to the device"
),
&TextureError::InvalidInfo(info) =>
write!(
f,
"Invalid TextureInfo (width, height, and levels must not \
be zero): {:?}\n",
info
),
&TextureError::IncorrectSize(expected) =>
write!(
f,
"Invalid data size provided to update the texture, \
expected size {:?}",
expected
),
}
}
}
pub type Size = u16;
pub type Bits = u8;
pub type NumSamples = u8;
pub type NumFragments = u8;
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
pub enum AaMode {
Msaa(NumSamples),
Eqaa(NumSamples, NumFragments),
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
#[repr(u8)]
pub enum Components {
R,
RG,
RGB,
RGBA,
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
#[allow(non_camel_case_types)]
pub enum Compression {
ETC2_RGB,
ETC2_SRGB,
ETC2_EAC_RGBA8,
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
#[allow(non_camel_case_types)]
pub enum Format {
Float(Components, FloatSize),
Integer(Components, Bits, IntSubType),
Unsigned(Components, Bits, IntSubType),
Compressed(Compression),
R3_G3_B2,
R5_G6_B5,
RGB5_A1,
RGB10_A2,
RGB10_A2UI,
R11F_G11F_B10F,
RGB9_E5,
BGRA8,
SRGB8,
SRGB8_A8,
DEPTH16,
DEPTH24,
DEPTH32F,
DEPTH24_STENCIL8,
DEPTH32F_STENCIL8,
}
impl Format {
pub fn get_components(&self) -> Option<Components> {
Some(match *self {
Format::Float(c, _) => c,
Format::Integer(c, _, _) => c,
Format::Unsigned(c, _, _) => c,
Format::Compressed(_) => {
error!("Tried to get components of compressed texel!");
return None
},
Format::R3_G3_B2 |
Format::R5_G6_B5 |
Format::R11F_G11F_B10F |
Format::RGB9_E5 |
Format::SRGB8 => Components::RGB,
Format::RGB5_A1 |
Format::RGB10_A2 |
Format::RGB10_A2UI |
Format::BGRA8 |
Format::SRGB8_A8 => Components::RGBA,
Format::DEPTH16 |
Format::DEPTH24 |
Format::DEPTH32F |
Format::DEPTH24_STENCIL8 |
Format::DEPTH32F_STENCIL8 => return None,
})
}
pub fn is_color(&self) -> bool {
match *self {
Format::DEPTH16 |
Format::DEPTH24 |
Format::DEPTH32F |
Format::DEPTH24_STENCIL8 |
Format::DEPTH32F_STENCIL8 => false,
_ => true,
}
}
pub fn has_depth(&self) -> bool {
match *self {
Format::DEPTH16 |
Format::DEPTH24 |
Format::DEPTH32F |
Format::DEPTH24_STENCIL8 |
Format::DEPTH32F_STENCIL8 => true,
_ => false,
}
}
pub fn has_stencil(&self) -> bool {
match *self {
Format::DEPTH24_STENCIL8 |
Format::DEPTH32F_STENCIL8 => true,
_ => false,
}
}
pub fn is_compressed(&self) -> bool {
match *self {
Format::Compressed(_) => true,
_ => false
}
}
pub fn does_convert_gamma(&self) -> bool {
match *self {
Format::SRGB8 |
Format::SRGB8_A8 |
Format::Compressed(Compression::ETC2_SRGB) => true,
_ => false,
}
}
}
pub static R8 : Format = Format::Unsigned(Components::R, 8, IntSubType::Normalized);
pub static RGBA8 : Format = Format::Unsigned(Components::RGBA, 8, IntSubType::Normalized);
pub static RGBA16F: Format = Format::Float(Components::RGBA, FloatSize::F16);
pub static RGBA32F: Format = Format::Float(Components::RGBA, FloatSize::F32);
#[allow(missing_docs)]
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
pub struct SurfaceInfo {
pub width: Size,
pub height: Size,
pub format: Format,
pub aa_mode: Option<AaMode>,
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
pub enum FilterMethod {
Scale,
Mipmap,
Bilinear,
Trilinear,
Anisotropic(u8)
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
pub enum TextureKind {
Texture1D,
Texture1DArray,
Texture2D,
Texture2DArray,
Texture2DMultiSample(AaMode),
Texture2DMultiSampleArray(AaMode),
TextureCube(CubeFace),
Texture3D,
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
#[allow(missing_docs)]
pub enum CubeFace {
PosZ,
NegZ,
PosX,
NegX,
PosY,
NegY
}
impl TextureKind {
pub fn get_aa_mode(&self) -> Option<AaMode> {
match *self {
TextureKind::Texture2DMultiSample(aa) => Some(aa),
TextureKind::Texture2DMultiSampleArray(aa) => Some(aa),
_ => None,
}
}
}
#[allow(missing_docs)]
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
pub struct TextureInfo {
pub width: Size,
pub height: Size,
pub depth: Size,
pub levels: u8,
pub kind: TextureKind,
pub format: Format,
}
#[allow(missing_docs)]
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
pub struct ImageInfo {
pub xoffset: Size,
pub yoffset: Size,
pub zoffset: Size,
pub width: Size,
pub height: Size,
pub depth: Size,
pub format: Format,
pub mipmap: u8,
}
impl Default for ImageInfo {
fn default() -> ImageInfo {
ImageInfo {
xoffset: 0,
yoffset: 0,
zoffset: 0,
width: 0,
height: 1,
depth: 1,
format: RGBA8,
mipmap: 0
}
}
}
impl Default for TextureInfo {
fn default() -> TextureInfo {
TextureInfo {
width: 0,
height: 1,
depth: 1,
levels: !0,
kind: TextureKind::Texture2D,
format: RGBA8,
}
}
}
impl TextureInfo {
pub fn new() -> TextureInfo {
Default::default()
}
pub fn to_image_info(&self) -> ImageInfo {
ImageInfo {
xoffset: 0,
yoffset: 0,
zoffset: 0,
width: self.width,
height: self.height,
depth: self.depth,
format: self.format,
mipmap: 0,
}
}
pub fn to_surface_info(&self) -> SurfaceInfo {
SurfaceInfo {
width: self.width,
height: self.height,
format: self.format,
aa_mode: self.kind.get_aa_mode(),
}
}
pub fn contains(&self, img: &ImageInfo) -> bool {
self.width <= img.xoffset + img.width &&
self.height <= img.yoffset + img.height &&
self.depth <= img.zoffset + img.depth &&
self.format == img.format &&
img.mipmap < self.levels &&
self.kind.get_aa_mode().is_none()
}
}
impl ImageInfo {
pub fn new() -> ImageInfo { Default::default() }
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
pub enum WrapMode {
Tile,
Mirror,
Clamp,
}
#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Copy, Clone, Debug)]
pub enum ComparisonMode {
NoComparison,
CompareRefToTexture(state::Comparison)
}
#[derive(PartialEq, PartialOrd, Clone, Copy, Debug)]
pub struct SamplerInfo {
pub filtering: FilterMethod,
pub wrap_mode: (WrapMode, WrapMode, WrapMode),
pub lod_bias: f32,
pub lod_range: (f32, f32),
pub comparison: ComparisonMode
}
impl SamplerInfo {
pub fn new(filtering: FilterMethod, wrap: WrapMode) -> SamplerInfo {
SamplerInfo {
filtering: filtering,
wrap_mode: (wrap, wrap, wrap),
lod_bias: 0.0,
lod_range: (-1000.0, 1000.0),
comparison: ComparisonMode::NoComparison
}
}
}