|
- use std::fs::File;
- use std::io::{Read, Seek};
- use std::path::Path;
-
- use imagefmt::{read_from, ColFmt, Error as ImageFmtError};
-
- use crate::{
- error::Error,
- misc::{AsEnum, BindGuard, Bindable},
- };
-
- /* Texture */
-
- pub struct Texture {
- id: gl::GLuint,
- target: Target,
- filter_min: FilterMin,
- filter_mag: FilterMag,
- wrap_s: Wrap,
- wrap_t: Wrap,
- wrap_r: Wrap,
- }
-
- impl Texture {
- pub fn new(target: Target) -> Result<Self, Error> {
- let mut id = 0;
-
- Error::checked(|| gl::create_textures(target.as_enum(), 1, &mut id))?;
-
- Ok(Self {
- id,
- target,
- filter_min: FilterMin::Nearest,
- filter_mag: FilterMag::Nearest,
- wrap_s: Wrap::Repeat,
- wrap_t: Wrap::Repeat,
- wrap_r: Wrap::Repeat,
- })
- }
-
- pub fn id(&self) -> gl::GLuint {
- self.id
- }
-
- pub fn upload(&mut self, data: &Data, generate_mipmap: bool) -> Result<(), Error> {
- let info = data.format.info();
-
- if info.gl_format == 0 || info.gl_format_data == 0 || info.gl_format_internal == 0 {
- return Err(Error::TextureUnsupportedFormat);
- }
-
- let target = self.target.as_enum();
- let _guard = BindGuard::new(&*self);
-
- Error::checked(|| {
- gl::tex_image_2d(
- target,
- 0,
- info.gl_format_internal as gl::GLint,
- data.width as gl::GLint,
- data.height as gl::GLint,
- 0,
- info.gl_format,
- info.gl_format_data,
- data.buffer.as_ptr() as *const _,
- )
- })?;
-
- if generate_mipmap {
- Error::checked(|| gl::generate_mipmap(target))?;
- }
-
- self.setup()
- }
-
- pub fn set_filter(&mut self, min: FilterMin, mag: FilterMag) -> Result<(), Error> {
- self.filter_min = min;
- self.filter_mag = mag;
-
- self.setup()
- }
-
- pub fn set_wrap(&mut self, s: Wrap, t: Wrap, r: Wrap) -> Result<(), Error> {
- self.wrap_s = s;
- self.wrap_t = t;
- self.wrap_r = r;
-
- self.setup()
- }
-
- fn setup(&self) -> Result<(), Error> {
- Error::checked(|| {
- gl::texture_parameter_i(
- self.id,
- gl::TEXTURE_MIN_FILTER,
- self.filter_min.as_enum() as gl::GLint,
- )
- })?;
- Error::checked(|| {
- gl::texture_parameter_i(
- self.id,
- gl::TEXTURE_MAG_FILTER,
- self.filter_mag.as_enum() as gl::GLint,
- )
- })?;
- Error::checked(|| {
- gl::texture_parameter_i(
- self.id,
- gl::TEXTURE_WRAP_S,
- self.wrap_s.as_enum() as gl::GLint,
- )
- })?;
- Error::checked(|| {
- gl::texture_parameter_i(
- self.id,
- gl::TEXTURE_WRAP_T,
- self.wrap_t.as_enum() as gl::GLint,
- )
- })?;
- Error::checked(|| {
- gl::texture_parameter_i(
- self.id,
- gl::TEXTURE_WRAP_R,
- self.wrap_r.as_enum() as gl::GLint,
- )
- })?;
-
- Ok(())
- }
- }
-
- impl Drop for Texture {
- fn drop(&mut self) {
- gl::delete_textures(1, &self.id);
- }
- }
-
- impl Bindable for Texture {
- fn bind(&self) {
- gl::bind_texture(self.target.as_enum(), self.id);
- }
-
- fn unbind(&self) {
- gl::bind_texture(self.target.as_enum(), 0);
- }
- }
-
- /* Data */
-
- #[derive(Clone, Debug)]
- pub struct Data {
- width: usize,
- height: usize,
- format: Format,
- buffer: Vec<u8>,
- }
-
- impl Data {
- pub fn from_parts(width: usize, height: usize, format: Format, buffer: Vec<u8>) -> Self {
- Self {
- width,
- height,
- format,
- buffer,
- }
- }
-
- pub fn from_reader<R>(reader: &mut R) -> Result<Self, Error>
- where
- R: Read + Seek,
- {
- let image = read_from(reader, ColFmt::Auto)?;
-
- Ok(Self {
- width: image.w,
- height: image.h,
- format: match image.fmt {
- ColFmt::Y => Format::Luminance8ub1,
- ColFmt::YA => Format::Luminance8Alpha8ub2,
- ColFmt::AY => Format::Alpha8Luminance8ub2,
- ColFmt::RGB => Format::RGB8ub3,
- ColFmt::RGBA => Format::RGBA8ub4,
- ColFmt::BGR => Format::BGR8ub3,
- ColFmt::BGRA => Format::BGRA8ub4,
- ColFmt::ARGB => Format::ARGB8ub4,
- ColFmt::ABGR => Format::ABGR8ub4,
- ColFmt::Auto => {
- return Err(ImageFmtError::Internal("Unexpected Format: Auto").into())
- }
- },
- buffer: image.buf,
- })
- }
-
- pub fn from_file<P>(path: P) -> Result<Self, Error>
- where
- P: AsRef<Path>,
- {
- let mut file = File::open(path)?;
-
- Self::from_reader(&mut file)
- }
-
- pub fn format(&self) -> Format {
- self.format
- }
-
- pub fn width(&self) -> usize {
- self.width
- }
-
- pub fn height(&self) -> usize {
- self.height
- }
-
- pub fn convert<F>(&mut self, format: Format, func: F) -> Result<(), Error>
- where
- F: Fn(usize, usize, &mut PixelData),
- {
- let dst_info = format.info();
-
- let mut dst_descriptor = format.descriptor();
- let mut src_descriptor = self.format.descriptor();
-
- let mut tmp = Vec::with_capacity(self.width * self.height * dst_info.bits_per_pixel / 8);
-
- let mut src = self.buffer.as_slice();
- let mut dst = tmp.as_mut_slice();
- let mut data = PixelData::default();
-
- for x in 0..self.width {
- for y in 0..self.height {
- let b = src_descriptor.unmap(&mut data, src)?;
- src = &src[b..];
-
- func(x, y, &mut data);
-
- let b = dst_descriptor.map(&data, dst)?;
- dst = &mut dst[b..];
- }
- }
-
- self.buffer = tmp;
-
- Ok(())
- }
-
- pub fn convert_to(&mut self, format: Format) -> Result<(), Error> {
- if format == self.format {
- return Ok(());
- }
-
- if self.format.is_bit_equal(&format) {
- self.format = format;
-
- return Ok(());
- }
-
- let dst_info = format.info();
- let src_info = self.format.info();
-
- if src_info.same_size_channels(&dst_info) {
- self.convert(format, |_, _, _| {})
- } else {
- self.convert(format, |_, _, data| {
- data.r = data.r.map(|x| x * dst_info.r_max / src_info.r_max);
- data.g = data.g.map(|x| x * dst_info.g_max / src_info.g_max);
- data.b = data.b.map(|x| x * dst_info.b_max / src_info.b_max);
- data.a = data.a.map(|x| x * dst_info.a_max / src_info.a_max);
- })
- }
- }
- }
-
- /* FormatDescriptor */
-
- pub trait FormatDescriptor {
- fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error>;
- fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error>;
- }
-
- struct Luminance8ub1Descriptor;
-
- impl FormatDescriptor for Luminance8ub1Descriptor {
- fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
- check_len(&buf, 1)?;
-
- if data.has_rgb() {
- buf[0] = data.luminance() as u8;
- } else {
- buf[0] = data.a.unwrap_or(0) as u8;
- }
-
- Ok(1)
- }
-
- fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
- check_len(&buf, 1)?;
-
- data.r = Some(buf[0] as u32);
- data.g = Some(buf[0] as u32);
- data.b = Some(buf[0] as u32);
- data.a = None;
-
- Ok(1)
- }
- }
-
- struct Luminance8Alpha8ub2Descriptor;
-
- impl FormatDescriptor for Luminance8Alpha8ub2Descriptor {
- fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
- check_len(&buf, 2)?;
-
- buf[0] = data.luminance() as u8;
- buf[1] = data.a.unwrap_or(255) as u8;
-
- Ok(2)
- }
-
- fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
- check_len(&buf, 2)?;
-
- data.r = Some(buf[0] as u32);
- data.g = Some(buf[0] as u32);
- data.b = Some(buf[0] as u32);
- data.a = Some(buf[1] as u32);
-
- Ok(2)
- }
- }
-
- struct Alpha8Luminance8ub2Descriptor;
-
- impl FormatDescriptor for Alpha8Luminance8ub2Descriptor {
- fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
- check_len(&buf, 2)?;
-
- buf[0] = data.a.unwrap_or(255) as u8;
- buf[1] = data.luminance() as u8;
-
- Ok(2)
- }
-
- fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
- check_len(&buf, 2)?;
-
- data.r = Some(buf[1] as u32);
- data.g = Some(buf[1] as u32);
- data.b = Some(buf[1] as u32);
- data.a = Some(buf[0] as u32);
-
- Ok(2)
- }
- }
-
- struct RGB8ub3Descriptor;
-
- impl FormatDescriptor for RGB8ub3Descriptor {
- fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
- check_len(&buf, 3)?;
-
- buf[0] = data.r.unwrap_or(0) as u8;
- buf[1] = data.g.unwrap_or(0) as u8;
- buf[2] = data.b.unwrap_or(0) as u8;
-
- Ok(3)
- }
-
- fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
- check_len(&buf, 3)?;
-
- data.r = Some(buf[0] as u32);
- data.g = Some(buf[1] as u32);
- data.b = Some(buf[2] as u32);
- data.a = None;
-
- Ok(3)
- }
- }
-
- struct RGBA8ub4Descriptor;
-
- impl FormatDescriptor for RGBA8ub4Descriptor {
- fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
- check_len(&buf, 4)?;
-
- buf[0] = data.r.unwrap_or(0) as u8;
- buf[1] = data.g.unwrap_or(0) as u8;
- buf[2] = data.b.unwrap_or(0) as u8;
- buf[3] = data.a.unwrap_or(0) as u8;
-
- Ok(4)
- }
-
- fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
- check_len(&buf, 4)?;
-
- data.r = Some(buf[0] as u32);
- data.g = Some(buf[1] as u32);
- data.b = Some(buf[2] as u32);
- data.a = Some(buf[3] as u32);
-
- Ok(4)
- }
- }
-
- struct ARGB8ub4Descriptor;
-
- impl FormatDescriptor for ARGB8ub4Descriptor {
- fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
- check_len(&buf, 4)?;
-
- buf[0] = data.a.unwrap_or(0) as u8;
- buf[1] = data.r.unwrap_or(0) as u8;
- buf[2] = data.g.unwrap_or(0) as u8;
- buf[3] = data.b.unwrap_or(0) as u8;
-
- Ok(4)
- }
-
- fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
- check_len(&buf, 4)?;
-
- data.a = Some(buf[0] as u32);
- data.r = Some(buf[1] as u32);
- data.g = Some(buf[2] as u32);
- data.b = Some(buf[3] as u32);
-
- Ok(4)
- }
- }
-
- struct BGR8ub3Descriptor;
-
- impl FormatDescriptor for BGR8ub3Descriptor {
- fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
- check_len(&buf, 3)?;
-
- buf[0] = data.b.unwrap_or(0) as u8;
- buf[1] = data.g.unwrap_or(0) as u8;
- buf[2] = data.r.unwrap_or(0) as u8;
-
- Ok(3)
- }
-
- fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
- check_len(&buf, 3)?;
-
- data.b = Some(buf[1] as u32);
- data.g = Some(buf[2] as u32);
- data.r = Some(buf[3] as u32);
- data.a = None;
-
- Ok(3)
- }
- }
-
- struct BGRA8ub4Descriptor;
-
- impl FormatDescriptor for BGRA8ub4Descriptor {
- fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
- check_len(&buf, 4)?;
-
- buf[0] = data.b.unwrap_or(0) as u8;
- buf[1] = data.g.unwrap_or(0) as u8;
- buf[2] = data.r.unwrap_or(0) as u8;
- buf[3] = data.a.unwrap_or(0) as u8;
-
- Ok(4)
- }
-
- fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
- check_len(&buf, 4)?;
-
- data.b = Some(buf[0] as u32);
- data.g = Some(buf[1] as u32);
- data.r = Some(buf[2] as u32);
- data.a = Some(buf[3] as u32);
-
- Ok(4)
- }
- }
-
- struct ABGR8ub4Descriptor;
-
- impl FormatDescriptor for ABGR8ub4Descriptor {
- fn map(&mut self, data: &PixelData, buf: &mut [u8]) -> Result<usize, Error> {
- check_len(&buf, 4)?;
-
- buf[0] = data.a.unwrap_or(0) as u8;
- buf[1] = data.b.unwrap_or(0) as u8;
- buf[2] = data.g.unwrap_or(0) as u8;
- buf[3] = data.r.unwrap_or(0) as u8;
-
- Ok(4)
- }
-
- fn unmap(&mut self, data: &mut PixelData, buf: &[u8]) -> Result<usize, Error> {
- check_len(&buf, 4)?;
-
- data.a = Some(buf[0] as u32);
- data.b = Some(buf[1] as u32);
- data.g = Some(buf[2] as u32);
- data.r = Some(buf[3] as u32);
-
- Ok(4)
- }
- }
-
- fn check_len(buf: &[u8], len: usize) -> Result<(), Error> {
- if buf.len() < len {
- Err(Error::TextureBufferOverflow)
- } else {
- Ok(())
- }
- }
-
- /* PixelData */
-
- #[derive(Default)]
- pub struct PixelData {
- pub r: Option<u32>,
- pub g: Option<u32>,
- pub b: Option<u32>,
- pub a: Option<u32>,
- }
-
- impl PixelData {
- pub fn has_rgb(&self) -> bool {
- self.r.is_some() && self.g.is_some() && self.b.is_some()
- }
-
- pub fn luminance(&self) -> u32 {
- (LUMINANCE_WEIGHT_R * self.r.unwrap_or(0) as f32
- + LUMINANCE_WEIGHT_G * self.g.unwrap_or(0) as f32
- + LUMINANCE_WEIGHT_B * self.b.unwrap_or(0) as f32) as u32
- }
- }
-
- const LUMINANCE_WEIGHT_R: f32 = 0.30;
- const LUMINANCE_WEIGHT_G: f32 = 0.59;
- const LUMINANCE_WEIGHT_B: f32 = 0.11;
-
- /* FormatInfo */
-
- pub struct FormatInfo {
- pub gl_format: gl::GLenum,
- pub gl_format_data: gl::GLenum,
- pub gl_format_internal: gl::GLenum,
-
- pub format_gl_support: Format,
- pub format_with_alpha: Format,
- pub format_without_alpha: Format,
-
- pub bits_per_pixel: usize,
-
- pub r_max: u32,
- pub g_max: u32,
- pub b_max: u32,
- pub a_max: u32,
-
- pub r_bits: u32,
- pub g_bits: u32,
- pub b_bits: u32,
- pub a_bits: u32,
- }
-
- impl FormatInfo {
- pub fn same_size_channels(&self, other: &Self) -> bool {
- (self.r_bits == other.r_bits || self.r_bits == 0 || other.r_bits == 0)
- && (self.g_bits == other.g_bits || self.g_bits == 0 || other.g_bits == 0)
- && (self.b_bits == other.b_bits || self.b_bits == 0 || other.b_bits == 0)
- && (self.a_bits == other.a_bits || self.a_bits == 0 || other.a_bits == 0)
- }
- }
-
- static INFO_LUMINANCE8_UB1: FormatInfo = FormatInfo {
- gl_format: gl::LUMINANCE,
- gl_format_data: gl::UNSIGNED_BYTE,
- gl_format_internal: gl::LUMINANCE8,
- format_gl_support: Format::Luminance8ub1,
- format_with_alpha: Format::Luminance8Alpha8ub2,
- format_without_alpha: Format::Luminance8ub1,
- bits_per_pixel: 8,
- r_max: 255,
- g_max: 255,
- b_max: 255,
- a_max: 0,
- r_bits: 8,
- g_bits: 8,
- b_bits: 8,
- a_bits: 0,
- };
- static INFO_LUMINANCE8_ALPHA8_UB2: FormatInfo = FormatInfo {
- gl_format: gl::LUMINANCE_ALPHA,
- gl_format_data: gl::UNSIGNED_BYTE,
- gl_format_internal: gl::LUMINANCE8_ALPHA8,
- format_gl_support: Format::Luminance8Alpha8ub2,
- format_with_alpha: Format::Luminance8Alpha8ub2,
- format_without_alpha: Format::Luminance8ub1,
- bits_per_pixel: 16,
- r_max: 255,
- g_max: 255,
- b_max: 255,
- a_max: 255,
- r_bits: 8,
- g_bits: 8,
- b_bits: 8,
- a_bits: 8,
- };
- static INFO_ALPHA8_LUMINANCE8_UB2: FormatInfo = FormatInfo {
- gl_format: gl::LUMINANCE_ALPHA,
- gl_format_data: gl::UNSIGNED_BYTE,
- gl_format_internal: gl::LUMINANCE8_ALPHA8,
- format_gl_support: Format::Luminance8Alpha8ub2,
- format_with_alpha: Format::Alpha8Luminance8ub2,
- format_without_alpha: Format::Luminance8ub1,
- bits_per_pixel: 16,
- r_max: 255,
- g_max: 255,
- b_max: 255,
- a_max: 255,
- r_bits: 8,
- g_bits: 8,
- b_bits: 8,
- a_bits: 8,
- };
- static INFO_RGB8_UB3: FormatInfo = FormatInfo {
- gl_format: gl::RGB,
- gl_format_data: gl::UNSIGNED_BYTE,
- gl_format_internal: gl::RGB8,
- format_gl_support: Format::RGB8ub3,
- format_with_alpha: Format::RGBA8ub4,
- format_without_alpha: Format::RGB8ub3,
- bits_per_pixel: 24,
- r_max: 255,
- g_max: 255,
- b_max: 255,
- a_max: 0,
- r_bits: 8,
- g_bits: 8,
- b_bits: 8,
- a_bits: 0,
- };
- static INFO_RGBA8_UB4: FormatInfo = FormatInfo {
- gl_format: gl::RGBA,
- gl_format_data: gl::UNSIGNED_BYTE,
- gl_format_internal: gl::RGBA8,
- format_gl_support: Format::RGBA8ub4,
- format_with_alpha: Format::RGBA8ub4,
- format_without_alpha: Format::RGB8ub3,
- bits_per_pixel: 32,
- r_max: 255,
- g_max: 255,
- b_max: 255,
- a_max: 255,
- r_bits: 8,
- g_bits: 8,
- b_bits: 8,
- a_bits: 8,
- };
- static INFO_ARGB8_UB4: FormatInfo = FormatInfo {
- gl_format: gl::RGBA,
- gl_format_data: gl::UNSIGNED_INT_8_8_8_8_REV,
- gl_format_internal: gl::RGBA8,
- format_gl_support: Format::ARGB8ub4,
- format_with_alpha: Format::ARGB8ub4,
- format_without_alpha: Format::RGB8ub3,
- bits_per_pixel: 32,
- r_max: 255,
- g_max: 255,
- b_max: 255,
- a_max: 255,
- r_bits: 8,
- g_bits: 8,
- b_bits: 8,
- a_bits: 8,
- };
- static INFO_BGR8_UB3: FormatInfo = FormatInfo {
- gl_format: gl::BGR,
- gl_format_data: gl::UNSIGNED_BYTE,
- gl_format_internal: gl::RGB8,
- format_gl_support: Format::BGR8ub3,
- format_with_alpha: Format::BGRA8ub4,
- format_without_alpha: Format::BGR8ub3,
- bits_per_pixel: 24,
- r_max: 255,
- g_max: 255,
- b_max: 255,
- a_max: 0,
- r_bits: 8,
- g_bits: 8,
- b_bits: 8,
- a_bits: 0,
- };
- static INFO_BGRA8_UB4: FormatInfo = FormatInfo {
- gl_format: gl::BGR,
- gl_format_data: gl::UNSIGNED_BYTE,
- gl_format_internal: gl::RGBA8,
- format_gl_support: Format::BGRA8ub4,
- format_with_alpha: Format::BGRA8ub4,
- format_without_alpha: Format::BGR8ub3,
- bits_per_pixel: 32,
- r_max: 255,
- g_max: 255,
- b_max: 255,
- a_max: 255,
- r_bits: 8,
- g_bits: 8,
- b_bits: 8,
- a_bits: 8,
- };
- static INFO_ABGR8_UB4: FormatInfo = FormatInfo {
- gl_format: gl::BGR,
- gl_format_data: gl::UNSIGNED_INT_8_8_8_8_REV,
- gl_format_internal: gl::RGBA8,
- format_gl_support: Format::ABGR8ub4,
- format_with_alpha: Format::ABGR8ub4,
- format_without_alpha: Format::BGR8ub3,
- bits_per_pixel: 32,
- r_max: 255,
- g_max: 255,
- b_max: 255,
- a_max: 255,
- r_bits: 8,
- g_bits: 8,
- b_bits: 8,
- a_bits: 8,
- };
-
- /* Format */
-
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- pub enum Format {
- /// [LLLL_LLLL]
- Luminance8ub1,
- /// [LLLL_LLLL][AAAA_AAAA]
- Luminance8Alpha8ub2,
- /// [AAAA_AAAA][LLLL_LLLL]
- Alpha8Luminance8ub2,
-
- /// [RRRR_RRRR][GGGG_GGGG][BBBB_BBBB]
- RGB8ub3,
- /// [RRRR_RRRR][GGGG_GGGG][BBBB_BBBB][AAAA_AAAA]
- RGBA8ub4,
- /// [AAAA_AAAA][RRRR_RRRR][GGGG_GGGG][BBBB_BBBB]
- ARGB8ub4,
-
- /// [BBBB_BBBB][GGGG_GGGG][RRRR_RRRR]
- BGR8ub3,
- /// [BBBB_BBBB][GGGG_GGGG][RRRR_RRRR][AAAA_AAAA]
- BGRA8ub4,
- /// [AAAA_AAAA][BBBB_BBBB][GGGG_GGGG][RRRR_RRRR]
- ABGR8ub4,
- }
-
- impl Format {
- pub fn info(&self) -> &'static FormatInfo {
- match self {
- Format::Luminance8ub1 => &INFO_LUMINANCE8_UB1,
- Format::Luminance8Alpha8ub2 => &INFO_LUMINANCE8_ALPHA8_UB2,
- Format::Alpha8Luminance8ub2 => &INFO_ALPHA8_LUMINANCE8_UB2,
- Format::RGB8ub3 => &INFO_RGB8_UB3,
- Format::RGBA8ub4 => &INFO_RGBA8_UB4,
- Format::ARGB8ub4 => &INFO_ARGB8_UB4,
- Format::BGR8ub3 => &INFO_BGR8_UB3,
- Format::BGRA8ub4 => &INFO_BGRA8_UB4,
- Format::ABGR8ub4 => &INFO_ABGR8_UB4,
- }
- }
-
- pub fn descriptor(&self) -> Box<dyn FormatDescriptor> {
- match self {
- Format::Luminance8ub1 => Box::new(Luminance8ub1Descriptor),
- Format::Luminance8Alpha8ub2 => Box::new(Luminance8Alpha8ub2Descriptor),
- Format::Alpha8Luminance8ub2 => Box::new(Alpha8Luminance8ub2Descriptor),
- Format::RGB8ub3 => Box::new(RGB8ub3Descriptor),
- Format::RGBA8ub4 => Box::new(RGBA8ub4Descriptor),
- Format::ARGB8ub4 => Box::new(ARGB8ub4Descriptor),
- Format::BGR8ub3 => Box::new(BGR8ub3Descriptor),
- Format::BGRA8ub4 => Box::new(BGRA8ub4Descriptor),
- Format::ABGR8ub4 => Box::new(ABGR8ub4Descriptor),
- }
- }
-
- pub fn is_bit_equal(&self, _other: &Self) -> bool {
- false
- }
- }
-
- /* Target */
-
- pub enum Target {
- Texture1D,
- Texture2D,
- Texture3D,
- Texture1DArray,
- Texture2DArray,
- TextureRectangle,
- TextureCubeMap,
- TextureCubeMapArray,
- TextureBuffer,
- Texture2DMultisample,
- Texture2DMultisampleArray,
- }
-
- impl AsEnum for Target {
- fn as_enum(&self) -> gl::GLenum {
- match self {
- Self::Texture1D => gl::TEXTURE_1D,
- Self::Texture2D => gl::TEXTURE_2D,
- Self::Texture3D => gl::TEXTURE_3D,
- Self::Texture1DArray => gl::TEXTURE_1D_ARRAY,
- Self::Texture2DArray => gl::TEXTURE_2D_ARRAY,
- Self::TextureRectangle => gl::TEXTURE_RECTANGLE,
- Self::TextureCubeMap => gl::TEXTURE_CUBE_MAP,
- Self::TextureCubeMapArray => gl::TEXTURE_CUBE_MAP_ARRAY,
- Self::TextureBuffer => gl::TEXTURE_BUFFER,
- Self::Texture2DMultisample => gl::TEXTURE_2D_MULTISAMPLE,
- Self::Texture2DMultisampleArray => gl::TEXTURE_2D_MULTISAMPLE_ARRAY,
- }
- }
- }
-
- /* FilterMin */
-
- pub enum FilterMin {
- /// Returns the value of the texture element that is nearest
- /// (in Manhattan distance) to the specified texture coordinates.
- Nearest,
-
- /// Returns the weighted average of the four texture elements
- /// that are closest to the specified texture coordinates.
- /// These can include items wrapped or repeated from other parts
- /// of a texture, depending on the values of GL_TEXTURE_WRAP_S
- /// and GL_TEXTURE_WRAP_T, and on the exact mapping.
- Linear,
-
- /// Chooses the mipmap that most closely matches the size of the
- /// pixel being textured and uses the GL_NEAREST criterion (the
- /// texture element closest to the specified texture coordinates)
- /// to produce a texture value.
- NearestMipmapNearest,
-
- /// Chooses the mipmap that most closely matches the size of the pixel
- /// being textured and uses the GL_LINEAR criterion (a weighted average
- /// of the four texture elements that are closest to the specified
- /// texture coordinates) to produce a texture value.
- LinearMipmapNearest,
-
- /// Chooses the two mipmaps that most closely match the size of the pixel
- /// being textured and uses the GL_NEAREST criterion (the texture element
- /// closest to the specified texture coordinates ) to produce a texture
- /// value from each mipmap. The final texture value is a weighted average
- /// of those two values.
- NearestMipmapLinear,
-
- /// Chooses the two mipmaps that most closely match the size of the pixel
- /// being textured and uses the GL_LINEAR criterion (a weighted average of
- /// the texture elements that are closest to the specified texture coordinates)
- /// to produce a texture value from each mipmap. The final texture value
- /// is a weighted average of those two values.
- LinearMipmapLinear,
- }
-
- impl AsEnum for FilterMin {
- fn as_enum(&self) -> gl::GLenum {
- match self {
- Self::Nearest => gl::NEAREST,
- Self::Linear => gl::LINEAR,
- Self::NearestMipmapNearest => gl::NEAREST_MIPMAP_NEAREST,
- Self::LinearMipmapNearest => gl::LINEAR_MIPMAP_NEAREST,
- Self::NearestMipmapLinear => gl::NEAREST_MIPMAP_LINEAR,
- Self::LinearMipmapLinear => gl::LINEAR_MIPMAP_LINEAR,
- }
- }
- }
-
- /* FilterMag */
-
- pub enum FilterMag {
- /// Returns the value of the texture element that is nearest
- /// (in Manhattan distance) to the specified texture coordinates.
- Nearest,
-
- /// Returns the weighted average of the texture elements that are
- /// closest to the specified texture coordinates. These can include
- /// items wrapped or repeated from other parts of a texture, depending
- /// on the values of GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T, and on
- /// the exact mapping.
- Linear,
- }
-
- impl AsEnum for FilterMag {
- fn as_enum(&self) -> gl::GLenum {
- match self {
- Self::Nearest => gl::NEAREST,
- Self::Linear => gl::LINEAR,
- }
- }
- }
-
- /* Wrap */
-
- pub enum Wrap {
- ClampToEdge,
- ClampToBorder,
- MirrorRepeat,
- Repeat,
- MirrorClampToEdge,
- }
-
- impl AsEnum for Wrap {
- fn as_enum(&self) -> gl::GLenum {
- match self {
- Self::ClampToEdge => gl::CLAMP_TO_EDGE,
- Self::ClampToBorder => gl::CLAMP_TO_BORDER,
- Self::MirrorRepeat => gl::MIRRORED_REPEAT,
- Self::Repeat => gl::REPEAT,
- Self::MirrorClampToEdge => gl::MIRROR_CLAMP_TO_EDGE,
- }
- }
- }
|