grafix_toolbox/kit/opengl/texture/
sampler.rs1use super::*;
2
3#[macro_export]
4macro_rules! Sampler {
5 ($(($n: expr, $v: expr)),+) => {{
6 use $crate::GL::{macro_uses::sampler_use::id, gl::*};
7 let id = const { id(&[$($n, $v),+]) };
8 Sampler::pooled(id, &[$(($n, $v)),+])
9 }};
10}
11
12pub struct Sampler(pub(super) Rc<Obj<SamplerT>>);
13impl<S: Borrow<[(GLenum, GLenum)]>> From<S> for Sampler {
14 fn from(args: S) -> Self {
15 Obj::new()
16 .pipe(Rc::new)
17 .pipe(Self)
18 .tap(|s| args.borrow().iter().for_each(|&(p, v)| s.Parameter(p, v)))
19 }
20}
21impl Sampler {
22 pub fn Parameter(&mut self, name: GLenum, args: impl SamplerArg) {
23 args.apply(self.0.obj, name);
24 }
25 pub fn pooled(id: u32, args: &[(GLenum, GLenum)]) -> Self {
26 let p = LocalStatic!(HashMap<u32, rc::Weak<Obj<SamplerT>>>);
27
28 if let Some(w) = p.get(&id)
29 && let Some(s) = w.upgrade()
30 {
31 ASSERT!(
32 LocalStatic!(HashMap<u32, Vec<(u32, u32)>>)
33 .entry(id)
34 .or_insert(args.to_vec())
35 .iter()
36 .eq(args.iter()),
37 "Sampler collision"
38 );
39 return Self(s);
40 }
41
42 Self::from(args).tap(|s| p.insert(id, Rc::downgrade(&s.0)).sink())
43 }
44 pub fn linear() -> Self {
45 Sampler!(
46 (TEXTURE_MIN_FILTER, LINEAR),
47 (TEXTURE_MAG_FILTER, LINEAR),
48 (TEXTURE_WRAP_R, CLAMP_TO_EDGE),
49 (TEXTURE_WRAP_S, CLAMP_TO_EDGE),
50 (TEXTURE_WRAP_T, CLAMP_TO_EDGE)
51 )
52 }
53}
54
55pub trait SamplerArg {
56 fn apply(&self, _: u32, _: GLenum);
57}
58impl SamplerArg for GLenum {
59 fn apply(&self, obj: u32, name: GLenum) {
60 GL!(gl::SamplerParameteri(obj, name, i32(self)));
61 }
62}
63impl SamplerArg for f32 {
64 fn apply(&self, obj: u32, name: GLenum) {
65 GL!(gl::SamplerParameterf(obj, name, *self));
66 }
67}
68impl SamplerArg for Vec4 {
69 fn apply(&self, obj: u32, name: GLenum) {
70 let s = [*self];
71 GL!(gl::SamplerParameterfv(obj, name, s.as_ptr() as *const f32));
72 }
73}
74
75pub mod sampler_use {
76 pub use super::chksum::const_fnv1_u32 as id;
77}