1use glium::implement_uniform_block;
2use serde::{Deserialize, Serialize};
3
4pub enum LightEmissionType {
5 Source,
6 Ambient,
7}
8
9pub enum ShadowResolution {
10 Low,
11 Medium,
12 High,
13 Ultra,
14 Custom(u32),
15}
16
17impl ShadowResolution {
18 pub fn value(&self) -> u32 {
19 match self {
20 ShadowResolution::Low => 512,
21 ShadowResolution::Medium => 1024,
22 ShadowResolution::High => 2048,
23 ShadowResolution::Ultra => 4096,
24 ShadowResolution::Custom(v) => *v,
25 }
26 }
27}
28
29#[derive(Serialize, Deserialize)]
30pub struct LightSerializer {
31 pub position: [f32; 3],
32 pub color: [f32; 3],
33 pub intensity: f32,
34 pub direction: [f32; 3],
35 pub cast_shadow: bool,
36}
37
38#[derive(Copy, Clone)]
39pub struct Light {
40 pub position: [f32; 3],
41 pub color: [f32; 3],
42 pub intensity: f32,
43 pub direction: [f32; 3],
44 pub cast_shadow: bool
45}
46
47impl Light {
48 pub fn new(position: [f32; 3], color: [f32; 3], intensity: f32, direction: Option<[f32;3]>, cast_shadow: bool) -> Self {
49 Self {
50 position,
51 color,
52 intensity,
53 direction : direction.unwrap_or_else(|| [0.0, 0.0, 0.0]),
54 cast_shadow,
55 }
56 }
57
58 pub fn default() -> Self {
59 Light::new([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], 1.0, None, true)
60 }
61
62 pub fn is_directional(&self) -> bool {
63 self.direction != [0.0, 0.0, 0.0]
64 }
65
66 pub fn from_serializer(serializer: LightSerializer) -> Self {
67 Self {
68 position: serializer.position,
69 color: serializer.color,
70 intensity: serializer.intensity,
71 direction: serializer.direction,
72 cast_shadow: serializer.cast_shadow,
73 }
74 }
75
76 pub fn to_serializer(&self) -> LightSerializer {
77 LightSerializer {
78 position: self.position,
79 color: self.color,
80 intensity: self.intensity,
81 direction: self.direction,
82 cast_shadow: self.cast_shadow,
83 }
84 }
85}
86
87pub struct LightBlock {
88 pub position: [[f32; 4]; 4],
89 pub directions: [[f32; 4]; 4],
90 pub color: [[f32; 4]; 4],
91 pub intensity: [f32; 4],
92 pub cast_shadow: [i32; 4],
93 pub amount: i32,
94 pub ambient_color: [f32; 3],
95 pub ambient_intensity: f32,
96}
97
98impl std::fmt::Debug for LightBlock {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 f.debug_struct("LightBlock")
101 .field("position", &self.position)
102 .field("color", &self.color)
103 .field("intensity", &self.intensity)
104 .field("amount", &self.amount)
105 .field("ambient_color", &self.ambient_color)
106 .finish()
107 }
108}
109
110glium::implement_uniform_block!(Light, position, color, intensity, direction, cast_shadow);
111glium::implement_uniform_block!(LightBlock, position, directions, cast_shadow, color, intensity, amount, ambient_color, ambient_intensity);
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116
117 #[test]
118 fn shadow_resolution_values() {
119 assert_eq!(ShadowResolution::Low.value(), 512);
120 assert_eq!(ShadowResolution::Medium.value(), 1024);
121 assert_eq!(ShadowResolution::High.value(), 2048);
122 assert_eq!(ShadowResolution::Ultra.value(), 4096);
123 assert_eq!(ShadowResolution::Custom(333).value(), 333);
124 }
125}