grafix_toolbox/kit/opengl/texture/
sampler.rs

1use 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
12impl<S: AsRef<[(GLenum, GLenum)]>> From<S> for Sampler {
13	fn from(args: S) -> Self {
14		let mut s = Self::new();
15		args.as_ref().iter().for_each(|&(p, v)| s.Parameter(p, v));
16		s
17	}
18}
19impl Sampler {
20	pub fn pooled(id: u32, args: &[(GLenum, GLenum)]) -> Rc<Self> {
21		let p = LocalStatic!(HashMap<u32, Weak<Sampler>>);
22
23		if let Some(w) = p.get(&id) {
24			if let Some(s) = w.upgrade() {
25				ASSERT!(
26					LocalStatic!(HashMap<u32, Vec<(u32, u32)>>).entry(id).or_insert(args.to_vec()).iter().eq(args.iter()),
27					"Sampler param collision"
28				);
29				return s;
30			}
31		}
32
33		let s = Rc::new(args.into());
34		p.insert(id, Rc::downgrade(&s));
35		s
36	}
37	pub fn linear() -> Rc<Self> {
38		Sampler!(
39			(TEXTURE_MIN_FILTER, LINEAR),
40			(TEXTURE_WRAP_R, CLAMP_TO_EDGE),
41			(TEXTURE_WRAP_S, CLAMP_TO_EDGE),
42			(TEXTURE_WRAP_T, CLAMP_TO_EDGE)
43		)
44	}
45}
46
47pub type Sampler = Object<SamplObj>;
48impl Sampler {
49	#![allow(private_bounds)]
50	pub fn Parameter(&mut self, name: GLenum, args: impl SamplerArg) {
51		args.apply(self.obj, name);
52	}
53}
54
55trait 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}