grafix_toolbox/gui/primitive/
frame9.rs1use 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);