texture/
lib.rs

1#![deny(missing_docs)]
2
3//! A generic library for textures.
4//!
5//! This library is used in Piston for generic code when working with textures.
6//!
7//! The `ImageSize` trait is used for passing textures around for rendering.
8//! For more information, see
9//! [Piston-Graphics](https://github.com/pistondevelopers/graphics).
10
11pub mod ops;
12
13/// Implemented by all images to be used with generic algorithms.
14pub trait ImageSize {
15    /// Get the image size.
16    fn get_size(&self) -> (u32, u32);
17
18    /// Gets the image width.
19    #[inline(always)]
20    fn get_width(&self) -> u32 {
21        let (w, _) = self.get_size();
22        w
23    }
24
25    /// Gets the image height.
26    #[inline(always)]
27    fn get_height(&self) -> u32 {
28        let (_, h) = self.get_size();
29        h
30    }
31}
32
33/// Texture creation parameters.
34#[derive(Clone, Copy)]
35pub struct TextureSettings {
36    // Whether to convert gamma, treated as sRGB color space
37    convert_gamma: bool,
38    // Compress on GPU.
39    compress: bool,
40    // Generate mipmap chain.
41    generate_mipmap: bool,
42    // Filtering Mode for Minifying
43    min: Filter,
44    // Filtering Mode for Magnifying
45    mag: Filter,
46    // Filtering Mode for Minify Mipmapping
47    mipmap: Filter,
48    // Wrapping mode for s coordinate
49    wrap_u: Wrap,
50    // Wrapping mode for t coordinate
51    wrap_v: Wrap,
52    // Border Color if ClampToBorder is specified as wrap mode
53    border_color: [f32; 4],
54}
55
56impl TextureSettings {
57    /// Create default settings.
58    pub fn new() -> TextureSettings {
59        TextureSettings {
60            convert_gamma: false,
61            compress: false,
62            generate_mipmap: false,
63            min: Filter::Linear,
64            mag: Filter::Linear,
65            mipmap: Filter::Linear,
66            wrap_u: Wrap::ClampToEdge,
67            wrap_v: Wrap::ClampToEdge,
68            border_color: [0.0, 0.0, 0.0, 1.0],
69        }
70    }
71
72    /// Gets whether to convert gamma, treated as sRGB color space.
73    pub fn get_convert_gamma(&self) -> bool { self.convert_gamma }
74    /// Sets convert gamma.
75    pub fn set_convert_gamma(&mut self, val: bool) { self.convert_gamma = val; }
76    /// Sets convert gamma.
77    pub fn convert_gamma(mut self, val: bool) -> Self {
78        self.set_convert_gamma(val);
79        self
80    }
81
82    /// Gets wheter compress on the GPU.
83    pub fn get_compress(&self) -> bool { self.compress }
84    /// Sets compress.
85    pub fn set_compress(&mut self, val: bool) { self.compress = val; }
86    /// Sets compress.
87    pub fn compress(mut self, val: bool) -> Self {
88        self.set_compress(val);
89        self
90    }
91
92    /// Gets generate mipmap.
93    pub fn get_generate_mipmap(&self) -> bool { self.generate_mipmap }
94    /// Sets generate mipmap.
95    pub fn set_generate_mipmap(&mut self, val: bool) {
96        self.generate_mipmap = val;
97    }
98    /// Sets generate mipmap.
99    pub fn generate_mipmap(mut self, val: bool) -> Self {
100        self.set_generate_mipmap(val);
101        self
102    }
103
104    /// Gets minify filter.
105    pub fn get_min(&self) -> Filter { self.min }
106    /// Sets minify filter.
107    pub fn set_min(&mut self, val: Filter) {
108        self.min = val
109    }
110    /// Sets minify filter.
111    pub fn min(mut self, val: Filter) -> Self {
112        self.set_min(val);
113        self
114    }
115
116    /// Gets magnify filter
117    pub fn get_mag(&self) -> Filter { self.mag }
118    /// Sets magnify filter
119    pub fn set_mag(&mut self, val: Filter) {
120        self.mag = val;
121    }
122    /// Sets magnify filter
123    pub fn mag(mut self, val: Filter) -> Self {
124        self.set_mag(val);
125        self
126    }
127
128    /// Gets minify mipmap filter
129    pub fn get_mipmap(&self) -> Filter { self.mipmap }
130    /// Sets magnify mipmap filter, and sets generate_mipmap to true.
131    pub fn set_mipmap(&mut self, val: Filter) {
132        self.set_generate_mipmap(true);
133        self.mag = val;
134    }
135    /// Sets magnify mipmap filter, and sets generate_mipmap to true
136    pub fn mipmap(mut self, val: Filter) -> Self {
137        self.set_mag(val);
138        self
139    }
140
141    /// Returns the min and mag filter
142    pub fn get_filter(&self) -> (Filter, Filter) { (self.min, self.mag) }
143    /// Sets the min and mag filter
144    pub fn set_filter(&mut self, val: Filter) {
145        self.set_min(val);
146        self.set_mag(val);
147    }
148
149    /// Sets the min and mag filter
150    pub fn filter(mut self, val: Filter) -> Self {
151        self.set_filter(val);
152        self
153    }
154
155    /// Gets the wrapping mode for the u coordinate
156    pub fn get_wrap_u(&self) -> Wrap {
157        self.wrap_u
158    }
159    /// Sets the wrapping mode for the u coordinate
160    pub fn set_wrap_u(& mut self, val: Wrap) {
161        self.wrap_u = val
162    }
163    /// Sets the wrapping mode for the u coordinate
164    pub fn wrap_u(mut self, val: Wrap) -> Self {
165        self.set_wrap_u(val);
166        self
167    }
168
169    /// Gets the wrapping mode for the v coordinate
170    pub fn get_wrap_v(&self) -> Wrap {
171        self.wrap_v
172    }
173    /// Sets the wrapping mode for the v coordinate
174    pub fn set_wrap_v(& mut self, val: Wrap) {
175        self.wrap_v = val
176    }
177    /// Sets the wrapping mode for the v coordinate
178    pub fn wrap_v(mut self, val: Wrap) -> Self {
179        self.set_wrap_v(val);
180        self
181    }
182
183    /// Gets the border color
184    pub fn get_border_color(&self) -> [f32; 4] {
185        self.border_color
186    }
187    /// Sets the border color
188    pub fn set_border_color(&mut self, val: [f32; 4]) {
189        self.border_color = val
190    }
191    /// Sets the border color
192    pub fn border_color(mut self, val: [f32; 4]) -> Self {
193        self.set_border_color(val);
194        self
195    }
196
197}
198
199/// Texture format.
200#[derive(Copy, Clone, Debug)]
201pub enum Format {
202    /// `(red, green, blue, alpha)` with values 0-255.
203    Rgba8,
204}
205
206/// Implemented by texture operations.
207pub trait TextureOp<F> {
208    /// The error when performing an operation.
209    type Error: core::fmt::Debug;
210}
211
212/// Implemented by textures for creation.
213pub trait CreateTexture<F>: TextureOp<F> + ImageSize + Sized {
214    /// Create texture from memory.
215    fn create<S: Into<[u32; 2]>>(
216        factory: &mut F,
217        format: Format,
218        memory: &[u8],
219        size: S,
220        settings: &TextureSettings
221    ) -> Result<Self, Self::Error>;
222}
223
224/// Implemented by textures for updating.
225pub trait UpdateTexture<F>: TextureOp<F> + ImageSize + Sized {
226    /// Update the texture.
227    ///
228    /// The `offset` and `size` arguments represent the position and dimensions of the sub-section
229    /// of the texture that is to be updated with the given `memory`.
230    fn update<O, S>(
231        &mut self,
232        factory: &mut F,
233        format: Format,
234        memory: &[u8],
235        offset: O,
236        size: S,
237    ) -> Result<(), Self::Error>
238        where O: Into<[u32; 2]>,
239              S: Into<[u32; 2]>;
240}
241
242/// Sampling filter
243#[derive(Copy, Clone, Debug)]
244pub enum Filter {
245    /// A Weighted Linear Blend
246    Linear,
247    /// Nearest Texel
248    Nearest
249}
250
251/// Wrap mode
252#[derive(Copy, Clone, Debug, PartialEq)]
253pub enum Wrap {
254    /// Repeats the texture by ignoring the integer part of the coordinate.
255    Repeat,
256    /// Repeats the texture and mirrors it, when the integer part of the coordinate is odd.
257    MirroredRepeat,
258    /// The coordinate will be clamped between 0 and 1.
259    ClampToEdge,
260    /// Coordinates outside the range [0.0, 1.0] will be given a border color.
261    ClampToBorder,
262}