use gl;
use ContextExt;
use context::Context;
use version::{Api, Version};
#[derive(Copy, Clone, Debug)]
pub struct FormatNotSupportedError;
#[derive(Copy, Clone, Debug)]
pub enum TextureFormatRequest {
Specific(TextureFormat),
AnyFloatingPoint,
AnyCompressed,
AnySrgb,
AnyCompressedSrgb,
AnyIntegral,
AnyUnsigned,
AnyDepth,
AnyStencil,
AnyDepthStencil,
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ClientFormat {
U8,
U8U8,
U8U8U8,
U8U8U8U8,
I8,
I8I8,
I8I8I8,
I8I8I8I8,
U16,
U16U16,
U16U16U16,
U16U16U16U16,
I16,
I16I16,
I16I16I16,
I16I16I16I16,
U32,
U32U32,
U32U32U32,
U32U32U32U32,
I32,
I32I32,
I32I32I32,
I32I32I32I32,
U3U3U2,
U5U6U5,
U4U4U4U4,
U5U5U5U1,
U10U10U10U2,
F16,
F16F16,
F16F16F16,
F16F16F16F16,
F32,
F32F32,
F32F32F32,
F32F32F32F32,
}
impl ClientFormat {
pub fn get_size(&self) -> usize {
use std::mem;
match *self {
ClientFormat::U8 => 1 * mem::size_of::<u8>(),
ClientFormat::U8U8 => 2 * mem::size_of::<u8>(),
ClientFormat::U8U8U8 => 3 * mem::size_of::<u8>(),
ClientFormat::U8U8U8U8 => 4 * mem::size_of::<u8>(),
ClientFormat::I8 => 1 * mem::size_of::<i8>(),
ClientFormat::I8I8 => 2 * mem::size_of::<i8>(),
ClientFormat::I8I8I8 => 3 * mem::size_of::<i8>(),
ClientFormat::I8I8I8I8 => 4 * mem::size_of::<i8>(),
ClientFormat::U16 => 1 * mem::size_of::<u16>(),
ClientFormat::U16U16 => 2 * mem::size_of::<u16>(),
ClientFormat::U16U16U16 => 3 * mem::size_of::<u16>(),
ClientFormat::U16U16U16U16 => 4 * mem::size_of::<u16>(),
ClientFormat::I16 => 1 * mem::size_of::<i16>(),
ClientFormat::I16I16 => 2 * mem::size_of::<i16>(),
ClientFormat::I16I16I16 => 3 * mem::size_of::<i16>(),
ClientFormat::I16I16I16I16 => 4 * mem::size_of::<i16>(),
ClientFormat::U32 => 1 * mem::size_of::<u32>(),
ClientFormat::U32U32 => 2 * mem::size_of::<u32>(),
ClientFormat::U32U32U32 => 3 * mem::size_of::<u32>(),
ClientFormat::U32U32U32U32 => 4 * mem::size_of::<u32>(),
ClientFormat::I32 => 1 * mem::size_of::<i32>(),
ClientFormat::I32I32 => 2 * mem::size_of::<i32>(),
ClientFormat::I32I32I32 => 3 * mem::size_of::<i32>(),
ClientFormat::I32I32I32I32 => 4 * mem::size_of::<i32>(),
ClientFormat::U3U3U2 => (3 + 3 + 2) / 8,
ClientFormat::U5U6U5 => (5 + 6 + 5) / 8,
ClientFormat::U4U4U4U4 => (4 + 4 + 4 + 4) / 8,
ClientFormat::U5U5U5U1 => (5 + 5 + 5 + 1) / 8,
ClientFormat::U10U10U10U2 => (10 + 10 + 10 + 2) / 8,
ClientFormat::F16 => 16 / 8,
ClientFormat::F16F16 => (16 + 16) / 8,
ClientFormat::F16F16F16 => (16 + 16 + 16) / 8,
ClientFormat::F16F16F16F16 => (16 + 16 + 16 + 16) / 8,
ClientFormat::F32 => 1 * mem::size_of::<f32>(),
ClientFormat::F32F32 => 2 * mem::size_of::<f32>(),
ClientFormat::F32F32F32 => 3 * mem::size_of::<f32>(),
ClientFormat::F32F32F32F32 => 4 * mem::size_of::<f32>(),
}
}
pub fn get_num_components(&self) -> u8 {
match *self {
ClientFormat::U8 => 1,
ClientFormat::U8U8 => 2,
ClientFormat::U8U8U8 => 3,
ClientFormat::U8U8U8U8 => 4,
ClientFormat::I8 => 1,
ClientFormat::I8I8 => 2,
ClientFormat::I8I8I8 => 3,
ClientFormat::I8I8I8I8 => 4,
ClientFormat::U16 => 1,
ClientFormat::U16U16 => 2,
ClientFormat::U16U16U16 => 3,
ClientFormat::U16U16U16U16 => 4,
ClientFormat::I16 => 1,
ClientFormat::I16I16 => 2,
ClientFormat::I16I16I16 => 3,
ClientFormat::I16I16I16I16 => 4,
ClientFormat::U32 => 1,
ClientFormat::U32U32 => 2,
ClientFormat::U32U32U32 => 3,
ClientFormat::U32U32U32U32 => 4,
ClientFormat::I32 => 1,
ClientFormat::I32I32 => 2,
ClientFormat::I32I32I32 => 3,
ClientFormat::I32I32I32I32 => 4,
ClientFormat::U3U3U2 => 3,
ClientFormat::U5U6U5 => 3,
ClientFormat::U4U4U4U4 => 4,
ClientFormat::U5U5U5U1 => 4,
ClientFormat::U10U10U10U2 => 4,
ClientFormat::F16 => 1,
ClientFormat::F16F16 => 2,
ClientFormat::F16F16F16 => 3,
ClientFormat::F16F16F16F16 => 4,
ClientFormat::F32 => 1,
ClientFormat::F32F32 => 2,
ClientFormat::F32F32F32 => 3,
ClientFormat::F32F32F32F32 => 4,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UncompressedFloatFormat {
U8,
I8,
U16,
I16,
U8U8,
I8I8,
U16U16,
I16I16,
U3U32U,
U4U4U4,
U5U5U5,
U8U8U8,
I8I8I8,
U10U10U10,
U12U12U12,
I16I16I16,
U2U2U2U2,
U4U4U4U4,
U5U5U5U1,
U8U8U8U8,
I8I8I8I8,
U10U10U10U2,
U12U12U12U12,
U16U16U16U16,
F16,
F16F16,
F16F16F16,
F16F16F16F16,
F32,
F32F32,
F32F32F32,
F32F32F32F32,
F11F11F10,
F9F9F9,
}
impl UncompressedFloatFormat {
pub fn to_texture_format(self) -> TextureFormat {
TextureFormat::UncompressedFloat(self)
}
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SrgbFormat {
U8U8U8,
U8U8U8U8,
}
impl SrgbFormat {
pub fn to_texture_format(self) -> TextureFormat {
TextureFormat::Srgb(self)
}
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UncompressedIntFormat {
I8,
I16,
I32,
I8I8,
I16I16,
I32I32,
I8I8I8,
I16I16I16,
I32I32I32,
I8I8I8I8,
I16I16I16I16,
I32I32I32I32,
}
impl UncompressedIntFormat {
pub fn to_texture_format(self) -> TextureFormat {
TextureFormat::UncompressedIntegral(self)
}
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UncompressedUintFormat {
U8,
U16,
U32,
U8U8,
U16U16,
U32U32,
U8U8U8,
U16U16U16,
U32U32U32,
U8U8U8U8,
U16U16U16U16,
U32U32U32U32,
U10U10U10U2,
}
impl UncompressedUintFormat {
pub fn to_texture_format(self) -> TextureFormat {
TextureFormat::UncompressedUnsigned(self)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompressedFormat {
RgtcFormatU,
RgtcFormatI,
RgtcFormatUU,
RgtcFormatII,
BptcUnorm4,
BptcSignedFloat3,
BptcUnsignedFloat3,
S3tcDxt1NoAlpha,
S3tcDxt1Alpha,
S3tcDxt3Alpha,
S3tcDxt5Alpha,
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompressedSrgbFormat {
Bptc,
S3tcDxt1NoAlpha,
S3tcDxt1Alpha,
S3tcDxt3Alpha,
S3tcDxt5Alpha,
}
impl CompressedFormat {
pub fn to_texture_format(self) -> TextureFormat {
TextureFormat::CompressedFormat(self)
}
fn to_glenum_if_supported(&self, context: &Context) -> Result<gl::types::GLenum, FormatNotSupportedError> {
let version = context.get_version();
let extensions = context.get_extensions();
match *self {
CompressedFormat::RgtcFormatU => {
if version >= &Version(Api::Gl, 3, 0) {
Ok(gl::COMPRESSED_RED_RGTC1)
} else {
Err(FormatNotSupportedError)
}
},
CompressedFormat::RgtcFormatI => {
if version >= &Version(Api::Gl, 3, 0) {
Ok(gl::COMPRESSED_SIGNED_RED_RGTC1)
} else {
Err(FormatNotSupportedError)
}
},
CompressedFormat::RgtcFormatUU => {
if version >= &Version(Api::Gl, 3, 0) {
Ok(gl::COMPRESSED_RG_RGTC2)
} else {
Err(FormatNotSupportedError)
}
},
CompressedFormat::RgtcFormatII => {
if version >= &Version(Api::Gl, 3, 0) {
Ok(gl::COMPRESSED_SIGNED_RG_RGTC2)
} else {
Err(FormatNotSupportedError)
}
},
CompressedFormat::BptcUnorm4 => {
if version >= &Version(Api::Gl, 4, 2) || extensions.gl_arb_texture_compression_bptc {
Ok(gl::COMPRESSED_RGBA_BPTC_UNORM)
} else {
Err(FormatNotSupportedError)
}
},
CompressedFormat::BptcSignedFloat3 => {
if version >= &Version(Api::Gl, 4, 2) || extensions.gl_arb_texture_compression_bptc {
Ok(gl::COMPRESSED_RGB_BPTC_SIGNED_FLOAT)
} else {
Err(FormatNotSupportedError)
}
},
CompressedFormat::BptcUnsignedFloat3 => {
if version >= &Version(Api::Gl, 4, 2) || extensions.gl_arb_texture_compression_bptc {
Ok(gl::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT)
} else {
Err(FormatNotSupportedError)
}
},
CompressedFormat::S3tcDxt1NoAlpha => {
if extensions.gl_ext_texture_compression_s3tc {
Ok(gl::COMPRESSED_RGB_S3TC_DXT1_EXT)
} else {
Err(FormatNotSupportedError)
}
},
CompressedFormat::S3tcDxt1Alpha => {
if extensions.gl_ext_texture_compression_s3tc {
Ok(gl::COMPRESSED_RGBA_S3TC_DXT1_EXT)
} else {
Err(FormatNotSupportedError)
}
},
CompressedFormat::S3tcDxt3Alpha => {
if extensions.gl_ext_texture_compression_s3tc {
Ok(gl::COMPRESSED_RGBA_S3TC_DXT3_EXT)
} else {
Err(FormatNotSupportedError)
}
},
CompressedFormat::S3tcDxt5Alpha => {
if extensions.gl_ext_texture_compression_s3tc {
Ok(gl::COMPRESSED_RGBA_S3TC_DXT5_EXT)
} else {
Err(FormatNotSupportedError)
}
},
}
}
}
impl CompressedSrgbFormat {
pub fn to_texture_format(self) -> TextureFormat {
TextureFormat::CompressedSrgbFormat(self)
}
fn to_glenum_if_supported(&self, context: &Context) -> Result<gl::types::GLenum, FormatNotSupportedError> {
let version = context.get_version();
let extensions = context.get_extensions();
match *self {
CompressedSrgbFormat::Bptc => {
if version >= &Version(Api::Gl, 4, 2) || extensions.gl_arb_texture_compression_bptc {
Ok(gl::COMPRESSED_SRGB_ALPHA_BPTC_UNORM)
} else {
Err(FormatNotSupportedError)
}
},
CompressedSrgbFormat::S3tcDxt1NoAlpha => {
if extensions.gl_ext_texture_compression_s3tc && extensions.gl_ext_texture_srgb {
Ok(gl::COMPRESSED_SRGB_S3TC_DXT1_EXT)
} else {
Err(FormatNotSupportedError)
}
},
CompressedSrgbFormat::S3tcDxt1Alpha => {
if extensions.gl_ext_texture_compression_s3tc && extensions.gl_ext_texture_srgb {
Ok(gl::COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT)
} else {
Err(FormatNotSupportedError)
}
},
CompressedSrgbFormat::S3tcDxt3Alpha => {
if extensions.gl_ext_texture_compression_s3tc && extensions.gl_ext_texture_srgb {
Ok(gl::COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT)
} else {
Err(FormatNotSupportedError)
}
},
CompressedSrgbFormat::S3tcDxt5Alpha => {
if extensions.gl_ext_texture_compression_s3tc && extensions.gl_ext_texture_srgb {
Ok(gl::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT)
} else {
Err(FormatNotSupportedError)
}
},
}
}
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DepthFormat {
I16,
I24,
I32,
F32,
}
impl DepthFormat {
pub fn to_texture_format(self) -> TextureFormat {
TextureFormat::DepthFormat(self)
}
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DepthStencilFormat {
I24I8,
F32I8,
}
impl DepthStencilFormat {
pub fn to_texture_format(self) -> TextureFormat {
TextureFormat::DepthStencilFormat(self)
}
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StencilFormat {
I1,
I4,
I8,
I16,
}
impl StencilFormat {
pub fn to_texture_format(self) -> TextureFormat {
TextureFormat::StencilFormat(self)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(missing_docs)]
pub enum TextureFormat {
UncompressedFloat(UncompressedFloatFormat),
UncompressedIntegral(UncompressedIntFormat),
UncompressedUnsigned(UncompressedUintFormat),
Srgb(SrgbFormat),
CompressedFormat(CompressedFormat),
CompressedSrgbFormat(CompressedSrgbFormat),
DepthFormat(DepthFormat),
StencilFormat(StencilFormat),
DepthStencilFormat(DepthStencilFormat),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ClientFormatAny {
ClientFormat(ClientFormat),
CompressedFormat(CompressedFormat),
CompressedSrgbFormat(CompressedSrgbFormat),
}
impl ClientFormatAny {
pub fn is_compressed(&self) -> bool {
match *self {
ClientFormatAny::ClientFormat(_) => false,
ClientFormatAny::CompressedFormat(_) => true,
ClientFormatAny::CompressedSrgbFormat(_) => true,
}
}
pub fn get_buffer_size(&self, width: u32, height: Option<u32>,
depth: Option<u32>, array_size: Option<u32>) -> usize {
match *self {
ClientFormatAny::ClientFormat(ref format) => {
format.get_size() * width as usize * height.unwrap_or(1) as usize *
depth.unwrap_or(1) as usize * array_size.unwrap_or(1) as usize
},
ClientFormatAny::CompressedFormat(CompressedFormat::S3tcDxt1Alpha) |
ClientFormatAny::CompressedSrgbFormat(CompressedSrgbFormat::S3tcDxt1Alpha) |
ClientFormatAny::CompressedFormat(CompressedFormat::S3tcDxt1NoAlpha) |
ClientFormatAny::CompressedSrgbFormat(CompressedSrgbFormat::S3tcDxt1NoAlpha) |
ClientFormatAny::CompressedFormat(CompressedFormat::RgtcFormatU) |
ClientFormatAny::CompressedFormat(CompressedFormat::RgtcFormatI) => {
let width = if width < 4 { 4 } else { width as usize };
let height = height.map(|height| if height < 4 { 4 } else { height as usize })
.expect("ST3C, RGTC and BPTC textures must have 2 dimensions");
if (width % 4) != 0 || (height % 4) != 0 {
panic!("ST3C, RGTC and BPTC textures must have a width and height multiple of 4.");
}
if depth.is_some() { panic!("ST3C, RGTC and BPTC textures are 2 dimension only.")
}
let uncompressed_bit_size = 4 * width as usize * height as usize *
depth.unwrap_or(1) as usize * array_size.unwrap_or(1) as usize;
uncompressed_bit_size / 8 },
ClientFormatAny::CompressedFormat(CompressedFormat::S3tcDxt3Alpha) |
ClientFormatAny::CompressedSrgbFormat(CompressedSrgbFormat::S3tcDxt3Alpha) |
ClientFormatAny::CompressedFormat(CompressedFormat::S3tcDxt5Alpha) |
ClientFormatAny::CompressedSrgbFormat(CompressedSrgbFormat::S3tcDxt5Alpha) |
ClientFormatAny::CompressedFormat(CompressedFormat::BptcUnorm4) |
ClientFormatAny::CompressedSrgbFormat(CompressedSrgbFormat::Bptc) |
ClientFormatAny::CompressedFormat(CompressedFormat::BptcSignedFloat3) |
ClientFormatAny::CompressedFormat(CompressedFormat::BptcUnsignedFloat3) |
ClientFormatAny::CompressedFormat(CompressedFormat::RgtcFormatUU) |
ClientFormatAny::CompressedFormat(CompressedFormat::RgtcFormatII) => {
let width = if width < 4 { 4 } else { width as usize };
let height = height.map(|height| if height < 4 { 4 } else { height as usize })
.expect("ST3C, RGTC and BPTC textures must have 2 dimensions");
if (width % 4) != 0 || (height % 4) != 0 {
panic!("ST3C, RGTC and BPTC textures must have a width and height multiple of 4.");
}
if depth.is_some() { panic!("ST3C, RGTC and BPTC textures are 2 dimension only.")
}
let uncompressed_bit_size = 4 * width as usize * height as usize *
depth.unwrap_or(1) as usize * array_size.unwrap_or(1) as usize;
uncompressed_bit_size / 4 },
}
}
pub fn get_num_components(&self) -> u8 {
match *self {
ClientFormatAny::ClientFormat(ref format) => format.get_num_components(),
_ => unimplemented!(),
}
}
#[doc(hidden)]
pub fn from_internal_compressed_format(internal: gl::types::GLenum) -> Option<ClientFormatAny> {
match internal {
gl::COMPRESSED_RGB_S3TC_DXT1_EXT => Some(ClientFormatAny::CompressedFormat(CompressedFormat::S3tcDxt1NoAlpha)),
gl::COMPRESSED_RGBA_S3TC_DXT1_EXT => Some(ClientFormatAny::CompressedFormat(CompressedFormat::S3tcDxt1Alpha)),
gl::COMPRESSED_RGBA_S3TC_DXT3_EXT => Some(ClientFormatAny::CompressedFormat(CompressedFormat::S3tcDxt3Alpha)),
gl::COMPRESSED_RGBA_S3TC_DXT5_EXT => Some(ClientFormatAny::CompressedFormat(CompressedFormat::S3tcDxt5Alpha)),
gl::COMPRESSED_SRGB_S3TC_DXT1_EXT => Some(ClientFormatAny::CompressedSrgbFormat(CompressedSrgbFormat::S3tcDxt1NoAlpha)),
gl::COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT => Some(ClientFormatAny::CompressedSrgbFormat(CompressedSrgbFormat::S3tcDxt1Alpha)),
gl::COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT => Some(ClientFormatAny::CompressedSrgbFormat(CompressedSrgbFormat::S3tcDxt3Alpha)),
gl::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT => Some(ClientFormatAny::CompressedSrgbFormat(CompressedSrgbFormat::S3tcDxt5Alpha)),
gl::COMPRESSED_RGBA_BPTC_UNORM => Some(ClientFormatAny::CompressedFormat(CompressedFormat::BptcUnorm4)),
gl::COMPRESSED_SRGB_ALPHA_BPTC_UNORM => Some(ClientFormatAny::CompressedSrgbFormat(CompressedSrgbFormat::Bptc)),
gl::COMPRESSED_RGB_BPTC_SIGNED_FLOAT => Some(ClientFormatAny::CompressedFormat(CompressedFormat::BptcSignedFloat3)),
gl::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT => Some(ClientFormatAny::CompressedFormat(CompressedFormat::BptcUnsignedFloat3)),
gl::COMPRESSED_RED_RGTC1 => Some(ClientFormatAny::CompressedFormat(CompressedFormat::RgtcFormatU)),
gl::COMPRESSED_SIGNED_RED_RGTC1 => Some(ClientFormatAny::CompressedFormat(CompressedFormat::RgtcFormatI)),
gl::COMPRESSED_RG_RGTC2 => Some(ClientFormatAny::CompressedFormat(CompressedFormat::RgtcFormatUU)),
gl::COMPRESSED_SIGNED_RG_RGTC2 => Some(ClientFormatAny::CompressedFormat(CompressedFormat::RgtcFormatII)),
_ => None,
}
}
}
pub fn format_request_to_glenum(context: &Context, client: Option<ClientFormatAny>,
format: TextureFormatRequest)
-> Result<(gl::types::GLenum, Option<gl::types::GLenum>),
FormatNotSupportedError>
{
let version = context.get_version();
let extensions = context.get_extensions();
let is_client_compressed = match client {
Some(ref client) => client.is_compressed(),
None => false,
};
Ok(match format {
TextureFormatRequest::AnyFloatingPoint => {
let size = client.map(|c| c.get_num_components());
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
match size {
Some(1) => (gl::RED, Some(gl::R8)),
Some(2) => (gl::RG, Some(gl::RG8)),
Some(3) => (gl::RGB, Some(gl::RGB8)),
Some(4) => (gl::RGBA, Some(gl::RGBA8)),
None => (gl::RGBA, Some(gl::RGBA8)),
_ => unreachable!(),
}
} else if version >= &Version(Api::Gl, 1, 1) {
match size {
Some(1) => if extensions.gl_arb_texture_rg {
(gl::RED, Some(gl::R8))
} else {
(gl::RED, None)
},
Some(2) => if extensions.gl_arb_texture_rg {
(gl::RG, Some(gl::RG8))
} else {
(gl::RG, None)
},
Some(3) => (gl::RGB, Some(gl::RGB8)),
Some(4) => (gl::RGBA, Some(gl::RGBA8)),
None => (gl::RGBA, Some(gl::RGBA8)),
_ => unreachable!(),
}
} else if version >= &Version(Api::Gl, 1, 0) {
(size.unwrap_or(4) as gl::types::GLenum, None)
} else if version >= &Version(Api::GlEs, 2, 0) {
match size {
Some(3) => {
if extensions.gl_oes_rgb8_rgba8 {
(gl::RGB, Some(gl::RGB8_OES))
} else if extensions.gl_arm_rgba8 {
(gl::RGB, Some(gl::RGBA8_OES))
} else {
(gl::RGB, Some(gl::RGB565))
}
},
Some(4) | None => {
if extensions.gl_oes_rgb8_rgba8 || extensions.gl_arm_rgba8 {
(gl::RGBA, Some(gl::RGBA8_OES))
} else {
(gl::RGBA, Some(gl::RGB5_A1))
}
},
_ => return Err(FormatNotSupportedError)
}
} else {
unreachable!();
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U8)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::R8, Some(gl::R8))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::I8)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::R8_SNORM, Some(gl::R8_SNORM))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U16)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::R16, Some(gl::R16))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::I16)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::R16_SNORM, Some(gl::R16_SNORM))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U8U8)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RG8, Some(gl::RG8))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::I8I8)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RG8_SNORM, Some(gl::RG8_SNORM))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U16U16)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RG16, Some(gl::RG16))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::I16I16)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RG16_SNORM, Some(gl::RG16_SNORM))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U3U32U)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::R3_G3_B2, Some(gl::R3_G3_B2))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U4U4U4)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB4, Some(gl::RGB4))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U5U5U5)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB5, Some(gl::RGB5))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U8U8U8)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB8, Some(gl::RGB8))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::I8I8I8)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB8_SNORM, Some(gl::RGB8_SNORM))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U10U10U10)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB10, Some(gl::RGB10))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U12U12U12)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB12, Some(gl::RGB12))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::I16I16I16)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB16_SNORM, Some(gl::RGB16_SNORM))
} else if version >= &Version(Api::Gl, 1, 1) {
(gl::RGB16, Some(gl::RGB16))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U2U2U2U2)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGBA2, Some(gl::RGBA2))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U4U4U4U4)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGBA4, Some(gl::RGBA4))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U5U5U5U1)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB5_A1, Some(gl::RGB5_A1))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U8U8U8U8)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGBA8, Some(gl::RGBA8))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::I8I8I8I8)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGBA8_SNORM, Some(gl::RGBA8_SNORM))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U10U10U10U2)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB10_A2, Some(gl::RGB10_A2))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U12U12U12U12)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGBA12, Some(gl::RGBA12))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::U16U16U16U16)) => {
if version >= &Version(Api::Gl, 1, 1) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGBA16, Some(gl::RGBA16))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::F16)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::R16F, Some(gl::R16F))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::F16F16)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RG16F, Some(gl::RG16F))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::F16F16F16)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB16F, Some(gl::RGB16F))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::F16F16F16F16)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGBA16F, Some(gl::RGBA16F))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::F32)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::R32F, Some(gl::R32F))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::F32F32)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RG32F, Some(gl::RG32F))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::F32F32F32)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB32F, Some(gl::RGB32F))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::F32F32F32F32)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGBA32F, Some(gl::RGBA32F))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::F11F11F10)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::R11F_G11F_B10F, Some(gl::R11F_G11F_B10F))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(UncompressedFloatFormat::F9F9F9)) => {
if version >= &Version(Api::Gl, 3, 0) || version >= &Version(Api::GlEs, 3, 0) {
(gl::RGB9_E5, Some(gl::RGB9_E5))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::AnyCompressed if is_client_compressed => {
let newformat = TextureFormat::CompressedFormat(match client {
Some(ClientFormatAny::CompressedFormat(format)) => format,
_ => unreachable!(),
});
try!(format_request_to_glenum(context, client, TextureFormatRequest::Specific(newformat)))
},
TextureFormatRequest::AnyCompressed => {
let size = client.map(|c| c.get_num_components());
if version >= &Version(Api::Gl, 1, 1) {
match size {
Some(1) => if version >= &Version(Api::Gl, 3, 0) || extensions.gl_arb_texture_rg {
(gl::COMPRESSED_RED, None)
} else {
(1, None)
},
Some(2) => if version >= &Version(Api::Gl, 3, 0) || extensions.gl_arb_texture_rg {
(gl::COMPRESSED_RG, None)
} else {
(2, None)
},
Some(3) => (gl::COMPRESSED_RGB, None),
Some(4) => (gl::COMPRESSED_RGBA, None),
None => (gl::COMPRESSED_RGBA, None),
_ => unreachable!(),
}
} else {
(size.unwrap_or(4) as gl::types::GLenum, None)
}
},
TextureFormatRequest::Specific(TextureFormat::CompressedFormat(format)) => {
try!(format.to_glenum_if_supported(context).map(|gl| (gl, Some(gl))))
},
TextureFormatRequest::AnySrgb => {
let size = client.map(|c| c.get_num_components());
if version >= &Version(Api::Gl, 2, 1) || version >= &Version(Api::GlEs, 3, 0) ||
extensions.gl_ext_texture_srgb
{
match size {
Some(1 ... 3) => (gl::SRGB8, Some(gl::SRGB8)),
Some(4) => (gl::SRGB8_ALPHA8, Some(gl::SRGB8_ALPHA8)),
None => (gl::SRGB8, Some(gl::SRGB8_ALPHA8)),
_ => unreachable!(),
}
} else {
try!(format_request_to_glenum(context, client,
TextureFormatRequest::AnyFloatingPoint))
}
},
TextureFormatRequest::Specific(TextureFormat::Srgb(SrgbFormat::U8U8U8)) => {
if version >= &Version(Api::Gl, 2, 1) || version >= &Version(Api::GlEs, 3, 0) ||
extensions.gl_ext_texture_srgb
{
(gl::SRGB8, Some(gl::SRGB8))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::Srgb(SrgbFormat::U8U8U8U8)) => {
if version >= &Version(Api::Gl, 2, 1) || version >= &Version(Api::GlEs, 3, 0) ||
extensions.gl_ext_texture_srgb
{
(gl::SRGB8_ALPHA8, Some(gl::SRGB8_ALPHA8))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::AnyCompressedSrgb if is_client_compressed => {
let newformat = TextureFormat::CompressedSrgbFormat(match client {
Some(ClientFormatAny::CompressedSrgbFormat(format)) => format,
_ => unreachable!(),
});
try!(format_request_to_glenum(context, client, TextureFormatRequest::Specific(newformat)))
},
TextureFormatRequest::AnyCompressedSrgb => {
let size = client.map(|c| c.get_num_components());
if version >= &Version(Api::Gl, 4, 0) || extensions.gl_ext_texture_srgb {
match size {
Some(1 ... 3) => (gl::COMPRESSED_SRGB, None),
Some(4) => (gl::COMPRESSED_SRGB_ALPHA, None),
None => (gl::COMPRESSED_SRGB_ALPHA, None),
_ => unreachable!(),
}
} else {
try!(format_request_to_glenum(context, client, TextureFormatRequest::AnySrgb))
}
},
TextureFormatRequest::Specific(TextureFormat::CompressedSrgbFormat(format)) => {
try!(format.to_glenum_if_supported(context).map(|gl| (gl, Some(gl))))
},
TextureFormatRequest::AnyIntegral => {
let size = client.map(|c| c.get_num_components());
if version >= &Version(Api::Gl, 3, 0) {
match size { Some(1) => (gl::R32I, Some(gl::R32I)),
Some(2) => (gl::RG32I, Some(gl::RG32I)),
Some(3) => (gl::RGB32I, Some(gl::RGB32I)),
Some(4) => (gl::RGBA32I, Some(gl::RGBA32I)),
None => (gl::RGBA32I, Some(gl::RGBA32I)),
_ => unreachable!(),
}
} else {
if !extensions.gl_ext_texture_integer {
return Err(FormatNotSupportedError);
}
match size { Some(1) => if extensions.gl_arb_texture_rg {
(gl::R32I, Some(gl::R32I))
} else {
return Err(FormatNotSupportedError);
},
Some(2) => if extensions.gl_arb_texture_rg {
(gl::RG32I, Some(gl::RG32I))
} else {
return Err(FormatNotSupportedError);
},
Some(3) => (gl::RGB32I_EXT, Some(gl::RGB32I_EXT)),
Some(4) => (gl::RGBA32I_EXT, Some(gl::RGBA32I_EXT)),
None => (gl::RGBA32I_EXT, Some(gl::RGBA32I_EXT)),
_ => unreachable!(),
}
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I8)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::R8I, Some(gl::R8I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I16)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::R16I, Some(gl::R16I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I32)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::R32I, Some(gl::R32I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I8I8)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::RG8I, Some(gl::RG8I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I16I16)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::RG16I, Some(gl::RG16I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I32I32)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::RG32I, Some(gl::RG32I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I8I8I8)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGB8I, Some(gl::RGB8I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I16I16I16)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGB16I, Some(gl::RGB16I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I32I32I32)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGB32I, Some(gl::RGB32I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I8I8I8I8)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGBA8I, Some(gl::RGBA8I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I16I16I16I16)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGBA16I, Some(gl::RGBA16I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(UncompressedIntFormat::I32I32I32I32)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGBA32I, Some(gl::RGBA32I))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::AnyUnsigned => {
let size = client.map(|c| c.get_num_components());
if version >= &Version(Api::Gl, 3, 0) {
match size { Some(1) => (gl::R32UI, Some(gl::R32I)),
Some(2) => (gl::RG32UI, Some(gl::RG32UI)),
Some(3) => (gl::RGB32UI, Some(gl::RGB32UI)),
Some(4) => (gl::RGBA32UI, Some(gl::RGBA32UI)),
None => (gl::RGBA32UI, Some(gl::RGBA32UI)),
_ => unreachable!(),
}
} else {
if !extensions.gl_ext_texture_integer {
return Err(FormatNotSupportedError);
}
match size { Some(1) => if extensions.gl_arb_texture_rg {
(gl::R32UI, Some(gl::R32UI))
} else {
return Err(FormatNotSupportedError);
},
Some(2) => if extensions.gl_arb_texture_rg {
(gl::RG32UI, Some(gl::RG32UI))
} else {
return Err(FormatNotSupportedError);
},
Some(3) => (gl::RGB32UI_EXT, Some(gl::RGB32UI_EXT)),
Some(4) => (gl::RGBA32UI_EXT, Some(gl::RGBA32UI_EXT)),
None => (gl::RGBA32UI_EXT, Some(gl::RGBA32UI_EXT)),
_ => unreachable!(),
}
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U8)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::R8UI, Some(gl::R8UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U16)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::R16UI, Some(gl::R16UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U32)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::R32UI, Some(gl::R32UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U8U8)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::RG8UI, Some(gl::RG8UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U16U16)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::RG16UI, Some(gl::RG16UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U32U32)) => {
if version >= &Version(Api::Gl, 3, 0) || (extensions.gl_ext_texture_integer &&
extensions.gl_arb_texture_rg)
{
(gl::RG32UI, Some(gl::RG32UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U8U8U8)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGB8UI, Some(gl::RGB8UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U16U16U16)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGB16UI, Some(gl::RGB16UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U32U32U32)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGB32UI, Some(gl::RGB32UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U8U8U8U8)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGBA8UI, Some(gl::RGBA8UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U16U16U16U16)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGBA16UI, Some(gl::RGBA16UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U32U32U32U32)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGBA32UI, Some(gl::RGBA32UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(UncompressedUintFormat::U10U10U10U2)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_texture_integer {
(gl::RGB10_A2UI, Some(gl::RGB10_A2UI))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::AnyDepth => {
if version >= &Version(Api::Gl, 2, 0) {
(gl::DEPTH_COMPONENT, Some(gl::DEPTH_COMPONENT24))
} else if version >= &Version(Api::Gl, 1, 4) || extensions.gl_arb_depth_texture ||
extensions.gl_oes_depth_texture
{
(gl::DEPTH_COMPONENT, None) } else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::DepthFormat(DepthFormat::I16)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_arb_depth_texture {
(gl::DEPTH_COMPONENT16, Some(gl::DEPTH_COMPONENT16))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::DepthFormat(DepthFormat::I24)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_arb_depth_texture {
(gl::DEPTH_COMPONENT24, Some(gl::DEPTH_COMPONENT24))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::DepthFormat(DepthFormat::I32)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_arb_depth_texture {
(gl::DEPTH_COMPONENT32, Some(gl::DEPTH_COMPONENT32))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::DepthFormat(DepthFormat::F32)) => {
if version >= &Version(Api::Gl, 3, 0) {
(gl::DEPTH_COMPONENT32F, Some(gl::DEPTH_COMPONENT32F))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::AnyStencil => {
if version < &Version(Api::Gl, 3, 0) {
return Err(FormatNotSupportedError);
}
return format_request_to_glenum(context, client,
TextureFormatRequest::Specific(
TextureFormat::UncompressedIntegral(
UncompressedIntFormat::I8)));
},
TextureFormatRequest::Specific(TextureFormat::StencilFormat(_)) => {
unimplemented!();
},
TextureFormatRequest::AnyDepthStencil => {
if version >= &Version(Api::Gl, 3, 0) {
(gl::DEPTH_STENCIL, Some(gl::DEPTH24_STENCIL8))
} else if extensions.gl_ext_packed_depth_stencil {
(gl::DEPTH_STENCIL_EXT, Some(gl::DEPTH24_STENCIL8_EXT))
} else if extensions.gl_oes_packed_depth_stencil {
(gl::DEPTH_STENCIL_OES, Some(gl::DEPTH24_STENCIL8_OES))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::DepthStencilFormat(DepthStencilFormat::I24I8)) => {
if version >= &Version(Api::Gl, 3, 0) || extensions.gl_ext_packed_depth_stencil ||
extensions.gl_oes_packed_depth_stencil
{
(gl::DEPTH24_STENCIL8, Some(gl::DEPTH24_STENCIL8))
} else {
return Err(FormatNotSupportedError);
}
},
TextureFormatRequest::Specific(TextureFormat::DepthStencilFormat(DepthStencilFormat::F32I8)) => {
if version >= &Version(Api::Gl, 3, 0) {
(gl::DEPTH32F_STENCIL8, Some(gl::DEPTH32F_STENCIL8))
} else {
return Err(FormatNotSupportedError);
}
},
})
}
pub fn client_format_to_glenum(context: &Context, client: ClientFormatAny, format: TextureFormatRequest)
-> Result<(gl::types::GLenum, gl::types::GLenum), FormatNotSupportedError>
{
match format {
TextureFormatRequest::AnyCompressed if client.is_compressed() =>
{
let extensions = context.get_extensions();
match client {
ClientFormatAny::CompressedFormat(client_format) => {
client_format.to_glenum_if_supported(context).map(|gl| (gl, gl))
},
_ => unreachable!(),
}
},
TextureFormatRequest::AnyCompressedSrgb if client.is_compressed() =>
{
match client {
ClientFormatAny::CompressedSrgbFormat(client_format) => {
client_format.to_glenum_if_supported(context).map(|gl| (gl, gl))
},
_ => unreachable!(),
}
},
TextureFormatRequest::Specific(TextureFormat::CompressedFormat(format))
if client.is_compressed() => {
format.to_glenum_if_supported(context).map(|gl| (gl, gl))
},
TextureFormatRequest::Specific(TextureFormat::CompressedSrgbFormat(format))
if client.is_compressed() => {
format.to_glenum_if_supported(context).map(|gl| (gl, gl))
},
TextureFormatRequest::AnyFloatingPoint | TextureFormatRequest::AnyCompressed |
TextureFormatRequest::AnySrgb | TextureFormatRequest::AnyCompressedSrgb |
TextureFormatRequest::Specific(TextureFormat::UncompressedFloat(_)) |
TextureFormatRequest::Specific(TextureFormat::Srgb(_)) |
TextureFormatRequest::Specific(TextureFormat::CompressedFormat(_)) |
TextureFormatRequest::Specific(TextureFormat::CompressedSrgbFormat(_)) =>
{
match client {
ClientFormatAny::ClientFormat(ClientFormat::U8) => Ok((gl::RED, gl::UNSIGNED_BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::U8U8) => Ok((gl::RG, gl::UNSIGNED_BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::U8U8U8) => Ok((gl::RGB, gl::UNSIGNED_BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::U8U8U8U8) => Ok((gl::RGBA, gl::UNSIGNED_BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::I8) => Ok((gl::RED, gl::BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::I8I8) => Ok((gl::RG, gl::BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::I8I8I8) => Ok((gl::RGB, gl::BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::I8I8I8I8) => Ok((gl::RGBA, gl::BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::U16) => Ok((gl::RED, gl::UNSIGNED_SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::U16U16) => Ok((gl::RG, gl::UNSIGNED_SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::U16U16U16) => Ok((gl::RGB, gl::UNSIGNED_SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::U16U16U16U16) => Ok((gl::RGBA, gl::UNSIGNED_SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::I16) => Ok((gl::RED, gl::SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::I16I16) => Ok((gl::RG, gl::SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::I16I16I16) => Ok((gl::RGB, gl::SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::I16I16I16I16) => Ok((gl::RGBA, gl::SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::U32) => Ok((gl::RED, gl::UNSIGNED_INT)),
ClientFormatAny::ClientFormat(ClientFormat::U32U32) => Ok((gl::RG, gl::UNSIGNED_INT)),
ClientFormatAny::ClientFormat(ClientFormat::U32U32U32) => Ok((gl::RGB, gl::UNSIGNED_INT)),
ClientFormatAny::ClientFormat(ClientFormat::U32U32U32U32) => Ok((gl::RGBA, gl::UNSIGNED_INT)),
ClientFormatAny::ClientFormat(ClientFormat::I32) => Ok((gl::RED, gl::INT)),
ClientFormatAny::ClientFormat(ClientFormat::I32I32) => Ok((gl::RG, gl::INT)),
ClientFormatAny::ClientFormat(ClientFormat::I32I32I32) => Ok((gl::RGB, gl::INT)),
ClientFormatAny::ClientFormat(ClientFormat::I32I32I32I32) => Ok((gl::RGBA, gl::INT)),
ClientFormatAny::ClientFormat(ClientFormat::U3U3U2) => Ok((gl::RGB, gl::UNSIGNED_BYTE_3_3_2)),
ClientFormatAny::ClientFormat(ClientFormat::U5U6U5) => Ok((gl::RGB, gl::UNSIGNED_SHORT_5_6_5)),
ClientFormatAny::ClientFormat(ClientFormat::U4U4U4U4) => Ok((gl::RGBA, gl::UNSIGNED_SHORT_4_4_4_4)),
ClientFormatAny::ClientFormat(ClientFormat::U5U5U5U1) => Ok((gl::RGBA, gl::UNSIGNED_SHORT_5_5_5_1)),
ClientFormatAny::ClientFormat(ClientFormat::U10U10U10U2) => Ok((gl::RGBA, gl::UNSIGNED_INT_10_10_10_2)),
ClientFormatAny::ClientFormat(ClientFormat::F16) => Ok((gl::RED, gl::HALF_FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F16F16) => Ok((gl::RG, gl::HALF_FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F16F16F16) => Ok((gl::RGB, gl::HALF_FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F16F16F16F16) => Ok((gl::RGBA, gl::HALF_FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F32) => Ok((gl::RED, gl::FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F32F32) => Ok((gl::RG, gl::FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F32F32F32) => Ok((gl::RGB, gl::FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F32F32F32F32) => Ok((gl::RGBA, gl::FLOAT)),
ClientFormatAny::CompressedFormat(_) => unreachable!(),
ClientFormatAny::CompressedSrgbFormat(_) => unreachable!(),
}
},
TextureFormatRequest::AnyIntegral | TextureFormatRequest::AnyUnsigned |
TextureFormatRequest::Specific(TextureFormat::UncompressedIntegral(_)) |
TextureFormatRequest::Specific(TextureFormat::UncompressedUnsigned(_)) =>
{
match client {
ClientFormatAny::ClientFormat(ClientFormat::U8) => Ok((gl::RED_INTEGER, gl::UNSIGNED_BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::U8U8) => Ok((gl::RG_INTEGER, gl::UNSIGNED_BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::U8U8U8) => Ok((gl::RGB_INTEGER, gl::UNSIGNED_BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::U8U8U8U8) => Ok((gl::RGBA_INTEGER, gl::UNSIGNED_BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::I8) => Ok((gl::RED_INTEGER, gl::BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::I8I8) => Ok((gl::RG_INTEGER, gl::BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::I8I8I8) => Ok((gl::RGB_INTEGER, gl::BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::I8I8I8I8) => Ok((gl::RGBA_INTEGER, gl::BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::U16) => Ok((gl::RED_INTEGER, gl::UNSIGNED_SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::U16U16) => Ok((gl::RG_INTEGER, gl::UNSIGNED_SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::U16U16U16) => Ok((gl::RGB_INTEGER, gl::UNSIGNED_SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::U16U16U16U16) => Ok((gl::RGBA_INTEGER, gl::UNSIGNED_SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::I16) => Ok((gl::RED_INTEGER, gl::SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::I16I16) => Ok((gl::RG_INTEGER, gl::SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::I16I16I16) => Ok((gl::RGB_INTEGER, gl::SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::I16I16I16I16) => Ok((gl::RGBA_INTEGER, gl::SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::U32) => Ok((gl::RED_INTEGER, gl::UNSIGNED_INT)),
ClientFormatAny::ClientFormat(ClientFormat::U32U32) => Ok((gl::RG_INTEGER, gl::UNSIGNED_INT)),
ClientFormatAny::ClientFormat(ClientFormat::U32U32U32) => Ok((gl::RGB_INTEGER, gl::UNSIGNED_INT)),
ClientFormatAny::ClientFormat(ClientFormat::U32U32U32U32) => Ok((gl::RGBA_INTEGER, gl::UNSIGNED_INT)),
ClientFormatAny::ClientFormat(ClientFormat::I32) => Ok((gl::RED_INTEGER, gl::INT)),
ClientFormatAny::ClientFormat(ClientFormat::I32I32) => Ok((gl::RG_INTEGER, gl::INT)),
ClientFormatAny::ClientFormat(ClientFormat::I32I32I32) => Ok((gl::RGB_INTEGER, gl::INT)),
ClientFormatAny::ClientFormat(ClientFormat::I32I32I32I32) => Ok((gl::RGBA_INTEGER, gl::INT)),
ClientFormatAny::ClientFormat(ClientFormat::U3U3U2) => Ok((gl::RGB_INTEGER, gl::UNSIGNED_BYTE_3_3_2)),
ClientFormatAny::ClientFormat(ClientFormat::U5U6U5) => Ok((gl::RGB_INTEGER, gl::UNSIGNED_SHORT_5_6_5)),
ClientFormatAny::ClientFormat(ClientFormat::U4U4U4U4) => Ok((gl::RGBA_INTEGER, gl::UNSIGNED_SHORT_4_4_4_4)),
ClientFormatAny::ClientFormat(ClientFormat::U5U5U5U1) => Ok((gl::RGBA_INTEGER, gl::UNSIGNED_SHORT_5_5_5_1)),
ClientFormatAny::ClientFormat(ClientFormat::U10U10U10U2) => Ok((gl::RGBA_INTEGER, gl::UNSIGNED_INT_10_10_10_2)),
ClientFormatAny::ClientFormat(ClientFormat::F16) => Ok((gl::RED_INTEGER, gl::HALF_FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F16F16) => Ok((gl::RG_INTEGER, gl::HALF_FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F16F16F16) => Ok((gl::RGB_INTEGER, gl::HALF_FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F16F16F16F16) => Ok((gl::RGBA_INTEGER, gl::HALF_FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F32) => Ok((gl::RED_INTEGER, gl::FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F32F32) => Ok((gl::RG_INTEGER, gl::FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F32F32F32) => Ok((gl::RGB_INTEGER, gl::FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F32F32F32F32) => Ok((gl::RGBA_INTEGER, gl::FLOAT)),
ClientFormatAny::CompressedFormat(_) => unreachable!(),
ClientFormatAny::CompressedSrgbFormat(_) => unreachable!(),
}
},
TextureFormatRequest::AnyDepth |
TextureFormatRequest::Specific(TextureFormat::DepthFormat(_)) =>
{
if client != ClientFormatAny::ClientFormat(ClientFormat::F32) {
panic!("Only ClientFormatAny::ClientFormat(ClientFormat::F32) can be used to upload on a depth texture");
}
Ok((gl::DEPTH_COMPONENT, gl::FLOAT))
}
TextureFormatRequest::AnyStencil |
TextureFormatRequest::Specific(TextureFormat::StencilFormat(_)) =>
{
match client {
ClientFormatAny::ClientFormat(ClientFormat::U8) => Ok((gl::RED_INTEGER, gl::UNSIGNED_BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::I8) => Ok((gl::RED_INTEGER, gl::BYTE)),
ClientFormatAny::ClientFormat(ClientFormat::U16) => Ok((gl::RED_INTEGER, gl::UNSIGNED_SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::I16) => Ok((gl::RED_INTEGER, gl::SHORT)),
ClientFormatAny::ClientFormat(ClientFormat::U32) => Ok((gl::RED_INTEGER, gl::UNSIGNED_INT)),
ClientFormatAny::ClientFormat(ClientFormat::I32) => Ok((gl::RED_INTEGER, gl::INT)),
ClientFormatAny::ClientFormat(ClientFormat::F16) => Ok((gl::RED_INTEGER, gl::HALF_FLOAT)),
ClientFormatAny::ClientFormat(ClientFormat::F32) => Ok((gl::RED_INTEGER, gl::FLOAT)),
_ => panic!("Can't upload to a stencil texture with more than one channel")
}
}
TextureFormatRequest::AnyDepthStencil |
TextureFormatRequest::Specific(TextureFormat::DepthStencilFormat(_)) =>
{
unimplemented!();
},
}
}