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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
use crate as wgpu;

/// Simplifies the construction of a `Sampler` with a set of reasonable defaults.
#[derive(Debug)]
pub struct SamplerBuilder {
    pub descriptor: wgpu::SamplerDescriptor<'static>,
}

impl<'b> SamplerBuilder {
    pub const DEFAULT_ADDRESS_MODE_U: wgpu::AddressMode = wgpu::AddressMode::ClampToEdge;
    pub const DEFAULT_ADDRESS_MODE_V: wgpu::AddressMode = wgpu::AddressMode::ClampToEdge;
    pub const DEFAULT_ADDRESS_MODE_W: wgpu::AddressMode = wgpu::AddressMode::ClampToEdge;
    pub const DEFAULT_MAG_FILTER: wgpu::FilterMode = wgpu::FilterMode::Linear;
    pub const DEFAULT_MIN_FILTER: wgpu::FilterMode = wgpu::FilterMode::Linear;
    pub const DEFAULT_MIPMAP_FILTER: wgpu::FilterMode = wgpu::FilterMode::Nearest;
    pub const DEFAULT_LOD_MIN_CLAMP: f32 = 0.0;
    pub const DEFAULT_LOD_MAX_CLAMP: f32 = 100.0;
    pub const DEFAULT_COMPARE: Option<wgpu::CompareFunction> = None;
    pub const DEFAULT_ANISOTROPY_CLAMP: u16 = 1;
    pub const DEFAULT_LABEL: &'static str = "nannou-sampler";
    pub const DEFAULT_BORDER_COLOR: Option<wgpu::SamplerBorderColor> = None;
    pub const DEFAULT_DESCRIPTOR: wgpu::SamplerDescriptor<'static> = wgpu::SamplerDescriptor {
        address_mode_u: Self::DEFAULT_ADDRESS_MODE_U,
        address_mode_v: Self::DEFAULT_ADDRESS_MODE_V,
        address_mode_w: Self::DEFAULT_ADDRESS_MODE_W,
        mag_filter: Self::DEFAULT_MAG_FILTER,
        min_filter: Self::DEFAULT_MIN_FILTER,
        mipmap_filter: Self::DEFAULT_MIPMAP_FILTER,
        lod_min_clamp: Self::DEFAULT_LOD_MIN_CLAMP,
        lod_max_clamp: Self::DEFAULT_LOD_MAX_CLAMP,
        compare: Self::DEFAULT_COMPARE,
        anisotropy_clamp: Self::DEFAULT_ANISOTROPY_CLAMP,
        label: Some(Self::DEFAULT_LABEL),
        border_color: Self::DEFAULT_BORDER_COLOR,
    };

    /// Begin building a `Sampler`, starting with the `Default` parameters.
    pub fn new() -> Self {
        Self::default()
    }

    /// How the implementation should behave when sampling outside of the texture coordinates range
    /// [0.0, 1.0].
    pub fn address_mode_u(mut self, mode: wgpu::AddressMode) -> Self {
        self.descriptor.address_mode_u = mode;
        self
    }

    /// How the implementation should behave when sampling outside of the texture coordinates range
    /// [0.0, 1.0].
    pub fn address_mode_v(mut self, mode: wgpu::AddressMode) -> Self {
        self.descriptor.address_mode_v = mode;
        self
    }

    /// How the implementation should behave when sampling outside of the texture coordinates range
    /// [0.0, 1.0].
    pub fn address_mode_w(mut self, mode: wgpu::AddressMode) -> Self {
        self.descriptor.address_mode_w = mode;
        self
    }

    /// How the implementation should behave when sampling outside of the texture coordinates range
    /// [0.0, 1.0].
    ///
    /// Applies the same address mode to all axes.
    pub fn address_mode(self, mode: wgpu::AddressMode) -> Self {
        self.address_mode_u(mode)
            .address_mode_v(mode)
            .address_mode_w(mode)
    }

    /// How the implementation should sample from the image when it is respectively larger than the
    /// original.
    pub fn mag_filter(mut self, filter: wgpu::FilterMode) -> Self {
        self.descriptor.mag_filter = filter;
        self
    }

    /// How the implementation should sample from the image when it is respectively smaller than
    /// the original.
    pub fn min_filter(mut self, filter: wgpu::FilterMode) -> Self {
        self.descriptor.min_filter = filter;
        self
    }

    /// How the implementation should choose which mipmap to use.
    pub fn mipmap_filter(mut self, filter: wgpu::FilterMode) -> Self {
        self.descriptor.mipmap_filter = filter;
        self
    }

    /// The minimum mipmap level to use.
    pub fn lod_min_clamp(mut self, min: f32) -> Self {
        self.descriptor.lod_min_clamp = min;
        self
    }

    /// The maximum mipmap level to use.
    pub fn lod_max_clamp(mut self, max: f32) -> Self {
        self.descriptor.lod_max_clamp = max;
        self
    }

    /// The comparison function to use, if any.
    pub fn compare(mut self, f: Option<wgpu::CompareFunction>) -> Self {
        self.descriptor.compare = f;
        self
    }

    /// The anisotropy level to clamp to, if any.
    pub fn anisotropy_clamp(mut self, clamp: u16) -> Self {
        self.descriptor.anisotropy_clamp = clamp;
        self
    }

    /// The label to use, if any.
    pub fn label(mut self, label: Option<&'static str>) -> Self {
        self.descriptor.label = label;
        self
    }

    /// Calls `device.create_sampler(&self.descriptor)` internally.
    pub fn build(&self, device: &wgpu::Device) -> wgpu::Sampler {
        device.create_sampler(&self.descriptor)
    }

    /// Consume the builder and produce the inner `SamplerDescriptor`.
    pub fn into_descriptor(self) -> wgpu::SamplerDescriptor<'static> {
        self.into()
    }
}

impl Default for SamplerBuilder {
    fn default() -> Self {
        SamplerBuilder {
            descriptor: Self::DEFAULT_DESCRIPTOR,
        }
    }
}

impl Into<wgpu::SamplerDescriptor<'static>> for SamplerBuilder {
    fn into(self) -> wgpu::SamplerDescriptor<'static> {
        self.descriptor
    }
}

impl From<wgpu::SamplerDescriptor<'static>> for SamplerBuilder {
    fn from(descriptor: wgpu::SamplerDescriptor<'static>) -> Self {
        SamplerBuilder { descriptor }
    }
}