Skip to main content

grafix_toolbox/gui/primitive/
frame9.rs

1use super::*;
2
3pub struct Frame9<'r> {
4	pub pos: Vec2,
5	pub size: Vec2,
6	pub corner: f32,
7	pub color: Color,
8	pub theme: &'r VTex2d<RGBA, u8>,
9}
10impl Frame9<'_> {
11	pub fn compare(&self, crop: &Geom, r: &Frame9Impl) -> State {
12		let Self { pos, size, corner, color, theme } = *self;
13		let xyzw = (State::XYZW | State::UV).or_def(geom_cmp(pos, size, crop, &r.base) || corner != r.corner);
14		let rgba = State::RGBA.or_def(color != r.base.color);
15		let ord = State::MISMATCH.or_def(!ptr::eq(theme, r.tex));
16		ord | xyzw | rgba
17	}
18	pub fn obj(self, crop: Geom) -> Frame9Impl {
19		let Self { pos, size, corner, color, theme } = self;
20		Frame9Impl { base: Base { pos, size, crop, color }, corner, tex: theme }
21	}
22}
23pub struct Frame9Impl {
24	base: Base,
25	corner: f32,
26	tex: *const VTex2d<RGBA, u8>,
27}
28impl Frame9Impl {
29	pub fn batchable(&self, r: &Self) -> bool {
30		self.tex == r.tex
31	}
32}
33impl Primitive for Frame9Impl {
34	fn base(&self) -> &Base {
35		&self.base
36	}
37	fn write_mesh(&self, aspect: Vec2, range: BatchedObj) {
38		let (crop, &Base { pos, size, color, .. }) = (self.base.bound_box(), self.base());
39		let c = size.min_comp() * self.corner.clamp(0., 0.5);
40		write_sprite9((aspect, pos, size, (c, c), crop, (0., 0., 1., 1.), color), range);
41	}
42	fn batch_draw(&self, b: &VaoBind<u16>, (offset, num): (u16, u16)) {
43		let s = LeakyStatic!(Shader, { [vs_gui__pos_col_tex, ps_gui__frame].pipe(Shader::pure) });
44
45		let tex = unsafe { &*self.tex };
46		let t = tex.atlas.Bind(sampler());
47		let (x, y, w, _) = tex.region;
48		let _ = Uniforms!(s, ("iTheme", t), ("iThemeCoord", (x, y, w - x)));
49		b.Draw((num, offset, gl::TRIANGLES));
50	}
51
52	fn vert_count(&self) -> u32 {
53		16
54	}
55	fn gen_idxs(&self, (start, size): (u16, u16)) -> Box<[u16]> {
56		sprite9_idxs((start, size))
57	}
58}
59
60SHADER!(
61	ps_gui__frame,
62	r"in vec4 glColor;
63	in vec2 glUV;
64	layout(location = 0) out vec4 glFragColor;
65	uniform sampler2D iTheme;
66	uniform vec3 iThemeCoord;
67
68	void main() {
69		float d = min(.9, length(glUV));
70		vec4 c = texture(iTheme, iThemeCoord.xy + vec2(d * iThemeCoord.z, 0));
71		glFragColor = glColor * c;
72	}"
73);