1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
//!
//! Contain texture asset definitions.
//!
pub(crate) mod texture2d;
pub use texture2d::*;
pub(crate) mod texture3d;
pub use texture3d::*;
pub use crate::prelude::f16;
use crate::Srgba;
///
/// Possible modes of interpolation which determines the texture output between texture pixels.
///
#[allow(missing_docs)]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Interpolation {
Nearest,
Linear,
CubicSpline,
}
impl Default for Interpolation {
fn default() -> Self {
Self::Linear
}
}
///
/// Possible wrapping modes for a texture which determines how the texture is applied outside of the
/// [0..1] uv coordinate range.
///
#[allow(missing_docs)]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Wrapping {
Repeat,
MirroredRepeat,
ClampToEdge,
}
///
/// The pixel/texel data for a [Texture2D] or [Texture3D].
///
/// If 2D data, the data array should start with the top left texel and then one row at a time.
/// The indices `(row, column)` into the 2D data would look like
/// ```notrust
/// [
/// (0, 0), (1, 0), .., // First row
/// (0, 1), (1, 1), .., // Second row
/// ..
/// ]
/// ```
/// If 3D data, the data array would look like the 2D data, one layer/image at a time.
/// The indices `(row, column, layer)` into the 3D data would look like
/// ```notrust
/// [
/// (0, 0, 0), (1, 0, 0), .., // First row in first layer
/// (0, 1, 0), (1, 1, 0), .., // Second row in first layer
/// ..
/// (0, 0, 1), (1, 0, 1), .., // First row in second layer
/// (0, 1, 1), (1, 1, 1), .., // Second row in second layer
/// ..
/// ]
/// ```
///
#[derive(Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum TextureData {
/// One byte in the red channel.
RU8(Vec<u8>),
/// One byte in the red and green channel.
RgU8(Vec<[u8; 2]>),
/// One byte in the red, green and blue channel.
RgbU8(Vec<[u8; 3]>),
/// One byte in the red, green, blue and alpha channel.
RgbaU8(Vec<[u8; 4]>),
/// 16-bit float in the red channel.
RF16(Vec<f16>),
/// 16-bit float in the red and green channel.
RgF16(Vec<[f16; 2]>),
/// 16-bit float in the red, green and blue channel.
RgbF16(Vec<[f16; 3]>),
/// 16-bit float in the red, green, blue and alpha channel.
RgbaF16(Vec<[f16; 4]>),
/// 32-bit float in the red channel.
RF32(Vec<f32>),
/// 32-bit float in the red and green channel.
RgF32(Vec<[f32; 2]>),
/// 32-bit float in the red, green and blue channel.
RgbF32(Vec<[f32; 3]>),
/// 32-bit float in the red, green, blue and alpha channel.
RgbaF32(Vec<[f32; 4]>),
}
impl std::fmt::Debug for TextureData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::RU8(values) => write!(f, "R u8 ({:?})", values.len()),
Self::RgU8(values) => write!(f, "RG u8 ({:?})", values.len()),
Self::RgbU8(values) => write!(f, "RGB u8 ({:?})", values.len()),
Self::RgbaU8(values) => write!(f, "RGBA u8 ({:?})", values.len()),
Self::RF16(values) => write!(f, "R f16 ({:?})", values.len()),
Self::RgF16(values) => write!(f, "RG f16 ({:?})", values.len()),
Self::RgbF16(values) => write!(f, "RGB f16 ({:?})", values.len()),
Self::RgbaF16(values) => write!(f, "RGBA f16 ({:?})", values.len()),
Self::RF32(values) => write!(f, "R f32 ({:?})", values.len()),
Self::RgF32(values) => write!(f, "RG f32 ({:?})", values.len()),
Self::RgbF32(values) => write!(f, "RGB f32 ({:?})", values.len()),
Self::RgbaF32(values) => write!(f, "RGBA f32 ({:?})", values.len()),
}
}
}
impl TextureData {
///
/// Converts the texture data to linear sRGB color space if the data is either
/// [TextureData::RgbU8] (assuming sRGB color space) or [TextureData::RgbaU8] (assuming sRGB color space with an alpha channel).
/// Does nothing if the data is any other data type.
///
pub fn to_linear_srgb(&mut self) {
match self {
TextureData::RgbU8(data) => data.iter_mut().for_each(|color| {
*color = Srgba::from(Srgba::from(*color).to_linear_srgb()).into();
}),
TextureData::RgbaU8(data) => data.iter_mut().for_each(|color| {
*color = Srgba::from(Srgba::from(*color).to_linear_srgb()).into();
}),
_ => {}
};
}
}