enigma_3d/
shader.rs

1use serde::{Deserialize, Serialize};
2use crate::logging::EnigmaMessage;
3use crate::smart_format;
4
5#[derive(Serialize, Deserialize, Clone)]
6pub struct ShaderSerializer {
7    fragment_shader: String,
8    vertex_shader: String,
9    geometry_shader: Option<String>
10}
11
12pub struct Shader {
13    pub fragment_shader: String,
14    pub vertex_shader: String,
15    pub geometry_shader: Option<String>
16}
17
18impl Shader {
19    pub fn new() -> Self {
20        Self {
21            fragment_shader: String::from(""),
22            vertex_shader: String::from(""),
23            geometry_shader: None,
24        }
25    }
26
27    pub fn from_serializer(serializer: ShaderSerializer) -> Self {
28        Self {
29            fragment_shader: serializer.fragment_shader,
30            vertex_shader: serializer.vertex_shader,
31            geometry_shader: serializer.geometry_shader,
32        }
33    }
34
35    pub fn to_serializer(&self) -> ShaderSerializer {
36        ShaderSerializer {
37            fragment_shader: self.fragment_shader.clone(),
38            vertex_shader: self.vertex_shader.clone(),
39            geometry_shader: self.geometry_shader.clone(),
40        }
41    }
42
43    pub fn set_fragment_shader(&mut self, fragment_shader: String) {
44        self.fragment_shader = fragment_shader;
45    }
46    pub fn set_vertex_shader(&mut self, vertex_shader: String) {
47        self.vertex_shader = vertex_shader;
48    }
49
50    pub fn set_geometry_shader(&mut self, geometry_shader: String) {
51        self.geometry_shader = Some(geometry_shader);
52    }
53
54    pub fn get_fragment_shader(&self) -> String {
55        self.fragment_shader.clone()
56    }
57    pub fn get_vertex_shader(&self) -> String {
58        self.vertex_shader.clone()
59    }
60
61    pub fn get_geometry_shader(&self) -> Option<String> {
62        self.geometry_shader.clone()
63    }
64
65    pub fn from_files(vertex_shader: &str, fragment_shader: &str, geometry_shader: Option<&str>) -> Self {
66        let vertex_shader = std::fs::read_to_string(vertex_shader).expect("Unable to read file");
67        let fragment_shader = std::fs::read_to_string(fragment_shader).expect("Unable to read file");
68        let geometry_shader = match geometry_shader {
69            Some(geometry_shader) => Some(std::fs::read_to_string(geometry_shader).expect("Unable to read file")),
70            None => None,
71        };
72        Self {
73            fragment_shader,
74            vertex_shader,
75            geometry_shader,
76        }
77    }
78
79    pub fn from_strings(vertex_shader: &str, fragment_shader: &str, geometry_shader: Option<&str>) -> Self {
80        Self {
81            fragment_shader: String::from(fragment_shader),
82            vertex_shader: String::from(vertex_shader),
83            geometry_shader: match geometry_shader {
84                Some(geometry_shader) => Some(String::from(geometry_shader)),
85                None => None,
86            },
87        }
88    }
89
90    pub fn log(&self) {
91        let mut logger = EnigmaMessage::new(Some(smart_format!("Vertex Shader:\n{}", self.vertex_shader).as_str()), true);
92        logger.extent(smart_format!("Fragment Shader:\n{}", self.fragment_shader).as_str());
93        match &self.geometry_shader {
94            Some(geometry_shader) => logger.extent(smart_format!("Geometry Shader:\n{}", geometry_shader).as_str()),
95            None => (),
96        }
97        logger.log();
98    }
99
100    pub fn default() -> Self {
101        let vertex_shader = r#"
102            #version 140
103            uniform float time;
104            uniform mat4 matrix;
105            in vec3 position;
106            void main() {
107                gl_Position = matrix * vec4(position, 1.0);
108            }
109        "#;
110
111        let fragment_shader = r#"
112            #version 140
113            uniform float time;
114            out vec4 color;
115            void main() {
116                color = vec4(1.0, 0.0, 1.0, 1.0);
117            }
118        "#;
119
120        Self {
121            fragment_shader: String::from(fragment_shader),
122            vertex_shader: String::from(vertex_shader),
123            geometry_shader: None,
124        }
125    }
126}
127
128impl Default for Shader {
129    fn default() -> Self {
130        Self::default()
131    }
132}
133
134impl std::fmt::Display for Shader {
135    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136        write!(f, "{}{}{}", self.vertex_shader, self.fragment_shader, match &self.geometry_shader {
137            Some(geometry_shader) => geometry_shader,
138            None => "",
139        })
140    }
141}
142
143impl std::fmt::Debug for Shader {
144    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145        write!(f, "{}{}{}", self.vertex_shader, self.fragment_shader, match &self.geometry_shader {
146            Some(geometry_shader) => geometry_shader,
147            None => "",
148        })
149    }
150}
151
152impl Clone for Shader {
153    fn clone(&self) -> Self {
154        Self {
155            fragment_shader: self.fragment_shader.clone(),
156            vertex_shader: self.vertex_shader.clone(),
157            geometry_shader: match &self.geometry_shader {
158                Some(geometry_shader) => Some(geometry_shader.clone()),
159                None => None,
160            },
161        }
162    }
163}