glium/uniforms/
sampler.rs

1use crate::ToGlEnum;
2use crate::gl;
3
4/// Function to use for out-of-bounds samples.
5///
6/// This is how GL must handle samples that are outside the texture.
7#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
8pub enum SamplerWrapFunction {
9    /// Samples at coord `x + 1` map to coord `x`.
10    Repeat,
11
12    /// Samples at coord `x + 1` map to coord `1 - x`.
13    Mirror,
14
15    /// Samples at coord `x + 1` map to coord `1`.
16    Clamp,
17
18    /// Use texture border.
19    BorderClamp,
20
21    /// Same as Mirror, but only for one repetition,
22    MirrorClamp
23}
24
25impl ToGlEnum for SamplerWrapFunction {
26    #[inline]
27    fn to_glenum(&self) -> gl::types::GLenum {
28        match *self {
29            SamplerWrapFunction::Repeat => gl::REPEAT,
30            SamplerWrapFunction::Mirror => gl::MIRRORED_REPEAT,
31            SamplerWrapFunction::Clamp => gl::CLAMP_TO_EDGE,
32            SamplerWrapFunction::BorderClamp => gl::CLAMP_TO_BORDER,
33            SamplerWrapFunction::MirrorClamp => gl::MIRROR_CLAMP_TO_EDGE,
34        }
35    }
36}
37
38/// The function that the GPU will use when loading the value of a texel.
39#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
40pub enum MagnifySamplerFilter {
41    /// The nearest texel will be loaded.
42    Nearest,
43
44    /// All nearby texels will be loaded and their values will be merged.
45    Linear,
46}
47
48impl ToGlEnum for MagnifySamplerFilter {
49    #[inline]
50    fn to_glenum(&self) -> gl::types::GLenum {
51        match *self {
52            MagnifySamplerFilter::Nearest => gl::NEAREST,
53            MagnifySamplerFilter::Linear => gl::LINEAR,
54        }
55    }
56}
57
58/// The function that the GPU will use when loading the value of a texel.
59#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
60pub enum MinifySamplerFilter {
61    /// The nearest texel will be loaded.
62    ///
63    /// Only uses the main texture, mipmaps are totally ignored.
64    Nearest,
65
66    /// All nearby texels will be loaded and their values will be merged.
67    ///
68    /// Only uses the main texture, mipmaps are totally ignored.
69    Linear,
70
71    /// The nearest texel of the nearest mipmap will be loaded.
72    NearestMipmapNearest,
73
74    /// Takes the nearest texel from the two nearest mipmaps, and merges them.
75    LinearMipmapNearest,
76
77    /// Same as `Linear`, but from the nearest mipmap.
78    NearestMipmapLinear,
79
80    /// Same as `Linear`, but from the two nearest mipmaps.
81    LinearMipmapLinear,
82}
83
84impl ToGlEnum for MinifySamplerFilter {
85    #[inline]
86    fn to_glenum(&self) -> gl::types::GLenum {
87        match *self {
88            MinifySamplerFilter::Nearest => gl::NEAREST,
89            MinifySamplerFilter::Linear => gl::LINEAR,
90            MinifySamplerFilter::NearestMipmapNearest => gl::NEAREST_MIPMAP_NEAREST,
91            MinifySamplerFilter::LinearMipmapNearest => gl::LINEAR_MIPMAP_NEAREST,
92            MinifySamplerFilter::NearestMipmapLinear => gl::NEAREST_MIPMAP_LINEAR,
93            MinifySamplerFilter::LinearMipmapLinear => gl::LINEAR_MIPMAP_LINEAR,
94        }
95    }
96}
97
98/// The depth texture comparison operation to use when comparing the r value to the value in the
99/// currently bound texture.
100#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
101pub enum DepthTextureComparison {
102    /// The r value is less than or equal to the texture value
103    LessOrEqual,
104
105    /// The r value is greater than or equal to the texture value
106    GreaterOrEqual,
107
108    /// The r value is less than to the texture value
109    Less,
110
111    /// The r value is greater than to the texture value
112    Greater,
113
114    /// The r value is equal to the texture value
115    Equal,
116
117    /// The r value is not equal to the texture value
118    NotEqual,
119
120    /// Always return 1.0 (true)
121    Always,
122
123    /// Never return 1.0 will return 0.0 (false)
124    Never,
125}
126
127impl ToGlEnum for DepthTextureComparison {
128    #[inline]
129    fn to_glenum(&self) -> gl::types::GLenum {
130        match *self {
131            DepthTextureComparison::LessOrEqual => gl::LEQUAL,
132            DepthTextureComparison::GreaterOrEqual => gl::GEQUAL,
133            DepthTextureComparison::Less => gl::LESS,
134            DepthTextureComparison::Greater => gl::GREATER,
135            DepthTextureComparison::Equal => gl::EQUAL,
136            DepthTextureComparison::NotEqual => gl::NOTEQUAL,
137            DepthTextureComparison::Always => gl::ALWAYS,
138            DepthTextureComparison::Never => gl::NEVER,
139        }
140    }
141}
142
143/// A sampler.
144#[derive(Debug, Hash, PartialEq, Eq)]
145pub struct Sampler<'t, T>(pub &'t T, pub SamplerBehavior);
146
147impl<'t, T: 't> Sampler<'t, T> {
148    /// Builds a new `Sampler` with default parameters.
149    pub fn new(texture: &'t T) -> Sampler<'t, T> {
150        Sampler(texture, Default::default())
151    }
152
153    /// Changes the wrap functions of all three coordinates.
154    pub fn wrap_function(mut self, function: SamplerWrapFunction) -> Sampler<'t, T> {
155        self.1.wrap_function = (function, function, function);
156        self
157    }
158
159    /// Changes the minifying filter of the sampler.
160    pub fn minify_filter(mut self, filter: MinifySamplerFilter) -> Sampler<'t, T> {
161        self.1.minify_filter = filter;
162        self
163    }
164
165    /// Changes the magnifying filter of the sampler.
166    pub fn magnify_filter(mut self, filter: MagnifySamplerFilter) -> Sampler<'t, T> {
167        self.1.magnify_filter = filter;
168        self
169    }
170
171    /// Sets the depth texture comparison method.
172    pub fn depth_texture_comparison(mut self, comparison: Option<DepthTextureComparison>) -> Sampler<'t, T> {
173        self.1.depth_texture_comparison = comparison;
174        self
175    }
176
177    /// Changes the magnifying filter of the sampler.
178    pub fn anisotropy(mut self, level: u16) -> Sampler<'t, T> {
179        self.1.max_anisotropy = level;
180        self
181    }
182}
183
184impl<'t, T: 't> Copy for Sampler<'t, T> {}
185
186impl<'t, T: 't> Clone for Sampler<'t, T> {
187    fn clone(&self) -> Self {
188        *self
189    }
190}
191
192/// Behavior of a sampler.
193// TODO: GL_TEXTURE_BORDER_COLOR, GL_TEXTURE_MIN_LOD, GL_TEXTURE_MAX_LOD, GL_TEXTURE_LOD_BIAS
194#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
195pub struct SamplerBehavior {
196    /// Functions to use for the X, Y, and Z coordinates.
197    pub wrap_function: (SamplerWrapFunction, SamplerWrapFunction, SamplerWrapFunction),
198
199    /// Filter to use when minifying the texture.
200    pub minify_filter: MinifySamplerFilter,
201
202    /// Filter to use when magnifying the texture.
203    pub magnify_filter: MagnifySamplerFilter,
204
205    /// The depth texture comparison function to use. Default value is None.
206    pub depth_texture_comparison: Option<DepthTextureComparison>,
207
208    /// `1` means no anisotropic filtering, any value above `1` sets the max anisotropy.
209    ///
210    /// ## Compatibility
211    ///
212    /// This parameter is always available. However it is ignored on hardware that does
213    /// not support anisotropic filtering.
214    ///
215    /// If you set the value to a value higher than what the hardware supports, it will
216    /// be clamped.
217    pub max_anisotropy: u16,
218}
219
220impl Default for SamplerBehavior {
221    #[inline]
222    fn default() -> SamplerBehavior {
223        SamplerBehavior {
224            wrap_function: (
225                SamplerWrapFunction::Mirror,
226                SamplerWrapFunction::Mirror,
227                SamplerWrapFunction::Mirror
228            ),
229            minify_filter: MinifySamplerFilter::LinearMipmapLinear,
230            magnify_filter: MagnifySamplerFilter::Linear,
231            depth_texture_comparison: None,
232            max_anisotropy: 1,
233        }
234    }
235}