concinnity_core/gfx/
view_modes.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
10#[repr(u32)]
11pub enum ViewMode {
12 #[default]
13 Lit = 0,
15 Unlit = 1,
17 Wireframe = 2,
19 Normals = 3,
21 Roughness = 4,
23 Occlusion = 5,
25 Depth = 6,
27}
28
29impl ViewMode {
30 pub const ALL: [ViewMode; 7] = [
32 ViewMode::Lit,
33 ViewMode::Unlit,
34 ViewMode::Wireframe,
35 ViewMode::Normals,
36 ViewMode::Roughness,
37 ViewMode::Occlusion,
38 ViewMode::Depth,
39 ];
40
41 pub fn is_flat(self) -> bool {
44 matches!(self, ViewMode::Unlit | ViewMode::Wireframe)
45 }
46
47 pub fn is_gbuffer_channel(self) -> bool {
50 matches!(
51 self,
52 ViewMode::Normals | ViewMode::Roughness | ViewMode::Occlusion | ViewMode::Depth
53 )
54 }
55
56 pub fn label(self) -> &'static str {
58 match self {
59 ViewMode::Lit => "Lit",
60 ViewMode::Unlit => "Unlit",
61 ViewMode::Wireframe => "Wireframe",
62 ViewMode::Normals => "Normals",
63 ViewMode::Roughness => "Roughness",
64 ViewMode::Occlusion => "Occlusion",
65 ViewMode::Depth => "Depth",
66 }
67 }
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq)]
75pub struct ShowFlags(pub u32);
76
77impl ShowFlags {
78 pub const SHADOWS: ShowFlags = ShowFlags(1 << 0);
80 pub const FOG: ShowFlags = ShowFlags(1 << 1);
82 pub const BLOOM: ShowFlags = ShowFlags(1 << 2);
84 pub const SSGI: ShowFlags = ShowFlags(1 << 3);
86 pub const SSR: ShowFlags = ShowFlags(1 << 4);
88 pub const LINES: ShowFlags = ShowFlags(1 << 5);
90
91 pub const LABELED: [(ShowFlags, &'static str); 6] = [
93 (ShowFlags::SHADOWS, "Shadows"),
94 (ShowFlags::FOG, "Fog"),
95 (ShowFlags::BLOOM, "Bloom"),
96 (ShowFlags::SSGI, "SSGI"),
97 (ShowFlags::SSR, "Reflections"),
98 (ShowFlags::LINES, "Lines"),
99 ];
100
101 pub const fn all() -> ShowFlags {
103 ShowFlags(
104 ShowFlags::SHADOWS.0
105 | ShowFlags::FOG.0
106 | ShowFlags::BLOOM.0
107 | ShowFlags::SSGI.0
108 | ShowFlags::SSR.0
109 | ShowFlags::LINES.0,
110 )
111 }
112
113 pub const fn contains(self, other: ShowFlags) -> bool {
115 self.0 & other.0 == other.0
116 }
117
118 #[must_use]
119 pub const fn toggled(self, other: ShowFlags) -> ShowFlags {
121 ShowFlags(self.0 ^ other.0)
122 }
123}
124
125impl Default for ShowFlags {
126 fn default() -> Self {
127 ShowFlags::all()
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn default_shows_everything() {
137 let all = ShowFlags::default();
138 for (flag, _) in ShowFlags::LABELED {
139 assert!(all.contains(flag));
140 }
141 assert_eq!(all, ShowFlags::all());
142 }
143
144 #[test]
145 fn toggling_clears_and_restores_one_bit() {
146 let some = ShowFlags::all().toggled(ShowFlags::FOG);
147 assert!(!some.contains(ShowFlags::FOG));
148 assert!(some.contains(ShowFlags::SHADOWS));
149 assert_eq!(some.toggled(ShowFlags::FOG), ShowFlags::all());
150 }
151
152 #[test]
153 fn mode_classes_partition_as_expected() {
154 assert!(!ViewMode::Lit.is_flat() && !ViewMode::Lit.is_gbuffer_channel());
155 assert!(ViewMode::Unlit.is_flat() && ViewMode::Wireframe.is_flat());
156 for m in [
157 ViewMode::Normals,
158 ViewMode::Roughness,
159 ViewMode::Occlusion,
160 ViewMode::Depth,
161 ] {
162 assert!(m.is_gbuffer_channel() && !m.is_flat());
163 }
164 assert_eq!(ViewMode::ALL.len(), 7);
165 }
166}