extern crate dds;
use gl;
use gl::types::*;
use std::mem;
use std::borrow::Borrow;
use self::dds::DXGIFormat;
use features::traits::{Image, CubemapImage};
impl<S: Borrow<[u8]>> Image for dds::Dds<S> {
type DataType = u8;
fn gl_internal_format_type(&self) -> Option<(GLenum, GLenum, GLenum)> {
match self.format() {
Ok(DXGIFormat::R32G32B32A32_FLOAT) => Some((gl::RGBA32F, gl::RGBA, gl::FLOAT)),
Ok(DXGIFormat::R32G32B32A32_UINT) => Some((gl::RGBA32UI, gl::RGBA_INTEGER, gl::UNSIGNED_INT)),
Ok(DXGIFormat::R32G32B32A32_SINT) => Some((gl::RGBA32I, gl::RGBA_INTEGER, gl::INT)),
Ok(DXGIFormat::R32G32B32_FLOAT) => Some((gl::RGB32F, gl::RGB, gl::FLOAT)),
Ok(DXGIFormat::R32G32B32_UINT) => Some((gl::RGB32UI, gl::RGB_INTEGER, gl::UNSIGNED_INT)),
Ok(DXGIFormat::R32G32B32_SINT) => Some((gl::RGB32I, gl::RGB_INTEGER, gl::INT)),
Ok(DXGIFormat::R16G16B16A16_FLOAT) => Some((gl::RGBA16F, gl::RGBA, gl::HALF_FLOAT)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::R16G16B16A16_UNORM) => Some((gl::RGBA16, gl::RGBA, gl::UNSIGNED_SHORT)),
Ok(DXGIFormat::R16G16B16A16_UINT) => Some((gl::RGBA16UI, gl::RGBA_INTEGER, gl::UNSIGNED_SHORT)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::R16G16B16A16_SNORM) => Some((gl::RGBA16_SNORM, gl::RGBA, gl::SHORT)),
Ok(DXGIFormat::R16G16B16A16_SINT) => Some((gl::RGBA16I, gl::RGBA_INTEGER, gl::SHORT)),
Ok(DXGIFormat::R32G32_FLOAT) => Some((gl::RG32F, gl::RG, gl::FLOAT)),
Ok(DXGIFormat::R32G32_UINT) => Some((gl::RG32UI, gl::RG_INTEGER, gl::UNSIGNED_INT)),
Ok(DXGIFormat::R32G32_SINT) => Some((gl::RG32I, gl::RG_INTEGER, gl::INT)),
Ok(DXGIFormat::D32_FLOAT_S8X24_UINT)
=> Some((gl::DEPTH32F_STENCIL8, gl::DEPTH_STENCIL, gl::FLOAT_32_UNSIGNED_INT_24_8_REV)),
Ok(DXGIFormat::R10G10B10A2_UNORM) => Some((gl::RGB10_A2, gl::RGBA, gl::UNSIGNED_INT)),
Ok(DXGIFormat::R10G10B10A2_UINT) => Some((gl::RGB10_A2UI, gl::RGBA_INTEGER, gl::UNSIGNED_INT)),
Ok(DXGIFormat::R11G11B10_FLOAT) => Some((gl::R11F_G11F_B10F, gl::RGB, gl::UNSIGNED_INT)),
Ok(DXGIFormat::R8G8B8A8_UNORM) => Some((gl::RGBA8, gl::RGBA, gl::UNSIGNED_BYTE)),
Ok(DXGIFormat::R8G8B8A8_UNORM_SRGB) => Some((gl::SRGB8_ALPHA8, gl::RGBA, gl::UNSIGNED_BYTE)),
Ok(DXGIFormat::R8G8B8A8_UINT) => Some((gl::RGBA8UI, gl::RGBA_INTEGER, gl::UNSIGNED_BYTE)),
Ok(DXGIFormat::R8G8B8A8_SNORM) => Some((gl::RGBA8_SNORM, gl::RGBA, gl::BYTE)),
Ok(DXGIFormat::R8G8B8A8_SINT) => Some((gl::RGBA8I, gl::RGBA_INTEGER, gl::BYTE)),
Ok(DXGIFormat::R16G16_FLOAT) => Some((gl::RG16F, gl::RG, gl::HALF_FLOAT)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::R16G16_UNORM) => Some((gl::RG16, gl::RG, gl::UNSIGNED_SHORT)),
Ok(DXGIFormat::R16G16_UINT) => Some((gl::RG16UI, gl::RG_INTEGER, gl::UNSIGNED_SHORT)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::R16G16_SNORM) => Some((gl::RG16_SNORM, gl::RG, gl::SHORT)),
Ok(DXGIFormat::R16G16_SINT) => Some((gl::RG16I, gl::RG_INTEGER, gl::SHORT)),
Ok(DXGIFormat::D32_FLOAT) => Some((gl::DEPTH_COMPONENT32F, gl::DEPTH_COMPONENT, gl::FLOAT)),
Ok(DXGIFormat::R32_FLOAT) => Some((gl::R32F, gl::RED, gl::FLOAT)),
Ok(DXGIFormat::R32_UINT) => Some((gl::R32UI, gl::RED_INTEGER, gl::UNSIGNED_INT)),
Ok(DXGIFormat::R32_SINT) => Some((gl::R32I, gl::RED_INTEGER, gl::INT)),
Ok(DXGIFormat::D24_UNORM_S8_UINT)
=> Some((gl::DEPTH24_STENCIL8, gl::DEPTH_STENCIL, gl::UNSIGNED_INT)),
Ok(DXGIFormat::R8G8_UNORM) => Some((gl::RG8, gl::RG, gl::UNSIGNED_BYTE)),
Ok(DXGIFormat::R8G8_UINT) => Some((gl::RG8UI, gl::RG_INTEGER, gl::UNSIGNED_BYTE)),
Ok(DXGIFormat::R8G8_SNORM) => Some((gl::RG8_SNORM, gl::RG, gl::BYTE)),
Ok(DXGIFormat::R8G8_SINT) => Some((gl::RG8I, gl::RG_INTEGER, gl::BYTE)),
Ok(DXGIFormat::R16_FLOAT) => Some((gl::R16F, gl::RED, gl::HALF_FLOAT)),
Ok(DXGIFormat::D16_UNORM) => Some((gl::DEPTH_COMPONENT16, gl::DEPTH_COMPONENT, gl::HALF_FLOAT)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::R16_UNORM) => Some((gl::R16, gl::RED, gl::UNSIGNED_SHORT)),
Ok(DXGIFormat::R16_UINT) => Some((gl::R16UI, gl::RED_INTEGER, gl::UNSIGNED_SHORT)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::R16_SNORM) => Some((gl::R16_SNORM, gl::RED, gl::SHORT)),
Ok(DXGIFormat::R16_SINT) => Some((gl::R16I, gl::RED_INTEGER, gl::SHORT)),
Ok(DXGIFormat::R8_UNORM) | Ok(DXGIFormat::A8_UNORM)
=> Some((gl::R8, gl::RED, gl::UNSIGNED_BYTE)),
Ok(DXGIFormat::R8_UINT) => Some((gl::R8UI, gl::RED_INTEGER, gl::UNSIGNED_BYTE)),
Ok(DXGIFormat::R8_SNORM) => Some((gl::R8_SNORM, gl::RED, gl::BYTE)),
Ok(DXGIFormat::R8_SINT) => Some((gl::R8I, gl::RED_INTEGER, gl::BYTE)),
Ok(DXGIFormat::R9G9B9E5_SHAREDEXP) => Some((gl::RGB9_E5, gl::RGB, gl::UNSIGNED_SHORT)),
Ok(DXGIFormat::BC1_UNORM)
=> Some((
gl::COMPRESSED_RGBA_S3TC_DXT1_EXT,
gl::COMPRESSED_RGBA_S3TC_DXT1_EXT,
gl::NONE)),
Ok(DXGIFormat::BC2_UNORM)
=> Some((
gl::COMPRESSED_RGBA_S3TC_DXT3_EXT,
gl::COMPRESSED_RGBA_S3TC_DXT3_EXT,
gl::NONE)),
Ok(DXGIFormat::BC3_UNORM)
=> Some((
gl::COMPRESSED_RGBA_S3TC_DXT5_EXT,
gl::COMPRESSED_RGBA_S3TC_DXT5_EXT,
gl::NONE)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::BC6H_UF16)
=> Some((
gl::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB,
gl::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB,
gl::NONE)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::BC6H_SF16)
=> Some((
gl::COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB,
gl::COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB,
gl::NONE)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::BC7_UNORM)
=> Some((
gl::COMPRESSED_RGBA_BPTC_UNORM_ARB,
gl::COMPRESSED_RGBA_BPTC_UNORM_ARB,
gl::NONE)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::BC7_UNORM_SRGB)
=> Some((
gl::COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB,
gl::COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB,
gl::NONE)),
#[cfg(any(feature="gles", feature="webgl"))]
Ok(DXGIFormat::BC6H_UF16)
=> Some((
gl::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT,
gl::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT,
gl::NONE)),
#[cfg(any(feature="gles", feature="webgl"))]
Ok(DXGIFormat::BC6H_SF16)
=> Some((
gl::COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT,
gl::COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT,
gl::NONE)),
#[cfg(any(feature="gles", feature="webgl"))]
Ok(DXGIFormat::BC7_UNORM)
=> Some((
gl::COMPRESSED_RGBA_BPTC_UNORM_EXT,
gl::COMPRESSED_RGBA_BPTC_UNORM_EXT,
gl::NONE)),
#[cfg(any(feature="gles", feature="webgl"))]
Ok(DXGIFormat::BC7_UNORM_SRGB)
=> Some((
gl::COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT,
gl::COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT,
gl::NONE)),
Ok(DXGIFormat::B5G5R5A1_UNORM) => Some((gl::RGB5_A1, gl::RGBA, gl::UNSIGNED_SHORT)),
#[cfg(not(any(feature="gles", feature="webgl")))]
Ok(DXGIFormat::B8G8R8A8_UNORM) | Ok(DXGIFormat::B8G8R8X8_UNORM)
=> Some((gl::RGBA8, gl::BGRA, gl::UNSIGNED_BYTE)),
#[cfg(any(feature="gles", feature="webgl"))]
Ok(DXGIFormat::B8G8R8A8_UNORM) | Ok(DXGIFormat::B8G8R8X8_UNORM)
=> Some((gl::RGBA8, gl::BGRA_EXT, gl::UNSIGNED_BYTE)),
Ok(_) => {
error!("Unkown format {:?}", self.format());
None
}
Err(err) => {
error!("Error retrieving dds format {}", err);
None
}
}
}
fn num_components(&self) -> usize{
let four_cc = self.fourcc_str();
if &four_cc == "DXT1" || &four_cc == "DXT3" || &four_cc == "DXT5" {
4
}else if &four_cc == "DX10" || self.fourcc() == 0{
if self.a_bitmask() != 0{
4
}else{
3
}
}else{
unreachable!()
}
}
fn width(&self, level: usize) -> usize{
let mut level0_w = self.width() as usize;
for _ in 0..level{
level0_w /= 2;
}
level0_w
}
fn height(&self, level: usize) -> usize{
let mut level0_h = self.height() as usize;
for _ in 0..level{
level0_h /= 2;
}
level0_h
}
fn pitch_bytes(&self, level: usize) -> usize{
let mut level0_p = self.pitch() / self.bytes_per_pixel();
for _ in 0..level{
level0_p /= 2;
}
level0_p * self.bytes_per_pixel()
}
fn bytes_per_pixel(&self) -> usize{
self.bpp().unwrap() / 8
}
fn pitch_components(&self, level: usize) -> usize{
let mut level0_p = self.pitch() / self.bytes_per_pixel();
for _ in 0..level{
level0_p /= 2;
}
level0_p
}
fn data(&self) -> &[u8]{
self.data()
}
fn levels(&self) -> usize{
self.mipmap_count()
}
fn mipmap(&self, level: usize) -> Option<&[u8]>{
self.mipmap(level).map(|dds| unsafe{ mem::transmute(dds.data()) })
}
fn is_gpu_compressed(&self) -> bool{
self.is_compressed()
}
}
impl<S: Borrow<[u8]>> CubemapImage for dds::Dds<S>{
fn mipmap_face(&self, level: usize, face: usize) -> Option<&[u8]>{
self.mipmap_face(level, face).ok().map(|dds| unsafe{ mem::transmute(dds.data()) })
}
}