1
2#![allow(non_upper_case_globals)]
3
4use crate::prelude::*;
5use std::{
6 collections::BTreeMap,
7 ffi::CString,
8 fmt::{self, Debug, Display, Formatter},
9 mem::{transmute, size_of},
10 path::Path,
11 ptr::null_mut,
12 rc::Rc,
13 string::FromUtf8Error,
14};
15use bincode::{Encode, Decode};
16
17#[derive(Clone)]
19pub enum ShaderError {
20 VSError(String),
22
23 GSError(String),
25
26 FSError(String),
28
29 CSError(String),
31
32 LinkageError(String),
34}
35
36#[derive(Encode, Decode, Debug, Clone, Copy, PartialEq)]
38pub enum ShaderType {
39 Draw,
40 Compute,
41}
42
43pub struct Shader {
45 glcore: Rc<GLCore>,
46 program: u32,
47 shader_type: ShaderType,
48}
49
50#[derive(Debug)]
52pub struct ShaderUse<'a> {
53 pub shader: &'a Shader,
54}
55
56#[derive(Encode, Decode, Debug, Clone)]
58pub struct ShaderBinary {
59 format: u32,
60 shader_type: ShaderType,
61 binary: Vec<u8>,
62}
63
64#[derive(Debug)]
66pub enum ShaderBinaryLoadError {
67 IOError(std::io::Error),
68 DecodeError(bincode::error::DecodeError),
69}
70
71#[derive(Debug)]
73pub enum ShaderBinarySaveError {
74 IOError(std::io::Error),
75 EncodeError(bincode::error::EncodeError),
76}
77
78#[derive(Clone, Copy)]
80pub enum ShaderInputType {
81 Float = GL_FLOAT as isize,
82 Vec2 = GL_FLOAT_VEC2 as isize,
83 Vec3 = GL_FLOAT_VEC3 as isize,
84 Vec4 = GL_FLOAT_VEC4 as isize,
85 Mat2 = GL_FLOAT_MAT2 as isize,
86 Mat3 = GL_FLOAT_MAT3 as isize,
87 Mat4 = GL_FLOAT_MAT4 as isize,
88 Mat2x3 = GL_FLOAT_MAT2x3 as isize,
89 Mat2x4 = GL_FLOAT_MAT2x4 as isize,
90 Mat3x2 = GL_FLOAT_MAT3x2 as isize,
91 Mat3x4 = GL_FLOAT_MAT3x4 as isize,
92 Mat4x2 = GL_FLOAT_MAT4x2 as isize,
93 Mat4x3 = GL_FLOAT_MAT4x3 as isize,
94 Int = GL_INT as isize,
95 IVec2 = GL_INT_VEC2 as isize,
96 IVec3 = GL_INT_VEC3 as isize,
97 IVec4 = GL_INT_VEC4 as isize,
98 UInt = GL_UNSIGNED_INT as isize,
99 UVec2 = GL_UNSIGNED_INT_VEC2 as isize,
100 UVec3 = GL_UNSIGNED_INT_VEC3 as isize,
101 UVec4 = GL_UNSIGNED_INT_VEC4 as isize,
102 Double = GL_DOUBLE as isize,
103 DVec2 = GL_DOUBLE_VEC2 as isize,
104 DVec3 = GL_DOUBLE_VEC3 as isize,
105 DVec4 = GL_DOUBLE_VEC4 as isize,
106 DMat2 = GL_DOUBLE_MAT2 as isize,
107 DMat3 = GL_DOUBLE_MAT3 as isize,
108 DMat4 = GL_DOUBLE_MAT4 as isize,
109 DMat2x3 = GL_DOUBLE_MAT2x3 as isize,
110 DMat2x4 = GL_DOUBLE_MAT2x4 as isize,
111 DMat3x2 = GL_DOUBLE_MAT3x2 as isize,
112 DMat3x4 = GL_DOUBLE_MAT3x4 as isize,
113 DMat4x2 = GL_DOUBLE_MAT4x2 as isize,
114 DMat4x3 = GL_DOUBLE_MAT4x3 as isize,
115}
116
117#[derive(Debug, Clone, Copy)]
119pub struct ShaderInputVarType {
120 pub type_: ShaderInputType,
121 pub size: i32,
122}
123
124impl Shader {
125 pub fn get_name(&self) -> u32 {
127 self.program
128 }
129
130 fn compile_shader(glcore: &GLCore, shader_type: u32, shader_source: &str) -> Result<u32, String> {
132 let shader = glcore.glCreateShader(shader_type);
133 let bytes: Vec<i8> = shader_source.bytes().map(|byte| -> i8 {byte as i8}).collect();
134 let ptr_to_bytes = bytes.as_ptr();
135 let length = bytes.len() as i32;
136 glcore.glShaderSource(shader, 1, &ptr_to_bytes as *const *const i8, &length as *const i32);
137 glcore.glCompileShader(shader);
138
139 let mut compiled: i32 = 0;
140 glcore.glGetShaderiv(shader, GL_COMPILE_STATUS, &mut compiled as *mut i32);
141 if compiled != 0 {
142 Ok(shader)
143 } else {
144 let mut output_len: i32 = 0;
145 glcore.glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &mut output_len as *mut i32);
146 let mut output = Vec::<u8>::new();
147 let mut output_len_ret: i32 = 0;
148 output.resize(output_len as usize, 0);
149 glcore.glGetShaderInfoLog(shader, output_len, &mut output_len_ret as *mut i32, output.as_mut_ptr() as *mut i8);
150 glcore.glDeleteShader(shader);
151 let output = String::from_utf8_lossy(&output).to_string();
152 Err(output)
153 }
154 }
155
156 fn link_program(glcore: &GLCore, program: u32) -> Result<(), ShaderError> {
158 glcore.glLinkProgram(program);
159 Self::get_linkage_status(glcore, program)
160 }
161
162 fn get_linkage_status(glcore: &GLCore, program: u32) -> Result<(), ShaderError> {
164 let mut linked: i32 = 0;
165 glcore.glGetProgramiv(program, GL_LINK_STATUS, &mut linked as *mut i32);
166 if linked != 0 {
167 Ok(())
168 } else {
169 let mut output_len: i32 = 0;
170 glcore.glGetProgramiv(program, GL_INFO_LOG_LENGTH, &mut output_len as *mut i32);
171 let mut output = Vec::<u8>::new();
172 let mut output_len_ret: i32 = 0;
173 output.resize(output_len as usize, 0);
174 glcore.glGetProgramInfoLog(program, output_len, &mut output_len_ret as *mut i32, output.as_mut_ptr() as *mut i8);
175 glcore.glDeleteProgram(program);
176 let output = String::from_utf8_lossy(&output).to_string();
177 Err(ShaderError::LinkageError(output))
178 }
179 }
180
181 pub fn new(glcore: Rc<GLCore>, vertex_shader: Option<&str>, geometry_shader: Option<&str>, fragment_shader: Option<&str>) -> Result<Self, ShaderError> {
183 let program = glcore.glCreateProgram();
184 if let Some(vertex_shader) = vertex_shader {
185 match Self::compile_shader(glcore.as_ref(), GL_VERTEX_SHADER, vertex_shader) {
186 Ok(shader) => {
187 glcore.glAttachShader(program, shader);
188 glcore.glDeleteShader(shader);
189 }
190 Err(output) => return Err(ShaderError::VSError(output)),
191 };
192 }
193 if let Some(geometry_shader) = geometry_shader {
194 match Self::compile_shader(glcore.as_ref(), GL_GEOMETRY_SHADER, geometry_shader) {
195 Ok(shader) => {
196 glcore.glAttachShader(program, shader);
197 glcore.glDeleteShader(shader);
198 }
199 Err(output) => return Err(ShaderError::GSError(output)),
200 };
201 }
202 if let Some(fragment_shader) = fragment_shader {
203 match Self::compile_shader(glcore.as_ref(), GL_FRAGMENT_SHADER, fragment_shader) {
204 Ok(shader) => {
205 glcore.glAttachShader(program, shader);
206 glcore.glDeleteShader(shader);
207 }
208 Err(output) => return Err(ShaderError::FSError(output)),
209 };
210 }
211 Self::link_program(glcore.as_ref(), program)?;
212 Ok(Self {
213 glcore,
214 program,
215 shader_type: ShaderType::Draw,
216 })
217 }
218
219 pub fn new_compute(glcore: Rc<GLCore>, shader_source: &str) -> Result<Self, ShaderError> {
221 let program = glcore.glCreateProgram();
222 match Self::compile_shader(glcore.as_ref(), GL_COMPUTE_SHADER, shader_source) {
223 Ok(shader) => {
224 glcore.glAttachShader(program, shader);
225 glcore.glDeleteShader(shader);
226 }
227 Err(output) => return Err(ShaderError::CSError(output)),
228 };
229 Self::link_program(glcore.as_ref(), program)?;
230 Ok(Self {
231 glcore,
232 program,
233 shader_type: ShaderType::Compute,
234 })
235 }
236
237 pub fn get_active_attribs(&self) -> Result<BTreeMap<String, ShaderInputVarType>, FromUtf8Error> {
239 let mut num_attribs: i32 = 0;
240 let mut max_length: i32 = 0;
241 self.glcore.glGetProgramiv(self.program, GL_ACTIVE_ATTRIBUTES, &mut num_attribs as *mut _);
242 self.glcore.glGetProgramiv(self.program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &mut max_length as *mut _);
243
244 let mut ret = BTreeMap::<String, ShaderInputVarType>::new();
245 for i in 0..num_attribs {
246 let mut name = vec![0i8; max_length as usize];
247 let mut size: i32 = 0;
248 let mut type_: u32 = 0;
249 self.glcore.glGetActiveAttrib(self.program, i as u32, max_length, null_mut::<i32>(), &mut size as *mut _, &mut type_ as *mut _, name.as_mut_ptr());
250 let name = String::from_utf8(unsafe{transmute::<Vec<i8>, Vec<u8>>(name)})?;
251 let name = name.trim_end_matches('\0').to_string();
252 let type_ = ShaderInputType::from(type_);
253 ret.insert(name, ShaderInputVarType{type_, size});
254 }
255 Ok(ret)
256 }
257
258 pub fn get_attrib_location(&self, attrib_name: &str) -> i32 {
260 let attrib_name = CString::new(attrib_name).unwrap();
261 self.glcore.glGetAttribLocation(self.program, attrib_name.as_ptr())
262 }
263
264 pub fn get_active_uniforms(&self) -> Result<BTreeMap<String, ShaderInputVarType>, FromUtf8Error> {
266 let mut num_uniforms: i32 = 0;
267 let mut max_length: i32 = 0;
268 self.glcore.glGetProgramiv(self.program, GL_ACTIVE_UNIFORMS, &mut num_uniforms as *mut _);
269 self.glcore.glGetProgramiv(self.program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &mut max_length as *mut _);
270
271 let mut ret = BTreeMap::<String, ShaderInputVarType>::new();
272 for i in 0..num_uniforms {
273 let mut name = vec![0i8; max_length as usize];
274 let mut size: i32 = 0;
275 let mut type_: u32 = 0;
276 self.glcore.glGetActiveUniform(self.program, i as u32, max_length, null_mut::<i32>(), &mut size as *mut _, &mut type_ as *mut _, name.as_mut_ptr());
277 let name = String::from_utf8(unsafe{transmute::<Vec<i8>, Vec<u8>>(name)})?;
278 let name = name.trim_end_matches('\0').to_string();
279 let type_ = ShaderInputType::from(type_);
280 ret.insert(name, ShaderInputVarType{type_, size});
281 }
282 Ok(ret)
283 }
284
285 pub fn get_uniform_location(&self, uniform_name: &str) -> i32 {
287 let uniform_name = CString::new(uniform_name).unwrap();
288 self.glcore.glGetUniformLocation(self.program, uniform_name.as_ptr())
289 }
290
291 pub fn get_program_binary(&self) -> ShaderBinary {
293 let mut binary_length = 0;
294 let mut binary_format = 0;
295 self.glcore.glGetProgramiv(self.program, GL_PROGRAM_BINARY_LENGTH, &mut binary_length as *mut _);
296 let mut binary = Vec::<u8>::new();
297 binary.resize(binary_length as usize, 0);
298 self.glcore.glGetProgramBinary(self.program, binary_length, null_mut(), &mut binary_format as *mut _, binary.as_mut_ptr() as *mut _);
299 ShaderBinary::new(binary_format, self.shader_type, binary)
300 }
301
302 pub fn from_program_binary(glcore: Rc<GLCore>, binary: &ShaderBinary) -> Result<Self, ShaderError> {
304 let program = glcore.glCreateProgram();
305 glcore.glProgramBinary(program, binary.format, binary.binary.as_ptr() as *const _, binary.binary.len() as i32);
306 match Self::get_linkage_status(&glcore, program) {
307 Ok(_) => Ok(Self {
308 glcore,
309 shader_type: binary.shader_type,
310 program,
311 }),
312 Err(e) => {
313 glcore.glDeleteProgram(program);
314 Err(e)
315 }
316 }
317 }
318
319 pub fn use_program<'a>(&'a self) -> ShaderUse<'a> {
321 ShaderUse::new(self)
322 }
323}
324
325impl<'a> ShaderUse<'a> {
326 fn new(shader: &'a Shader) -> Self {
328 shader.glcore.glUseProgram(shader.get_name());
329 Self {
330 shader,
331 }
332 }
333
334 pub fn dispatch_compute(&self, num_groups_x: u32, num_groups_y: u32, num_groups_z: u32) {
336 if self.shader.shader_type != ShaderType::Compute {
337 panic!("Only compute shaders could use the `dispatch_compute()` method.");
338 }
339 self.shader.glcore.glDispatchCompute(num_groups_x, num_groups_y, num_groups_z);
340 }
341
342 pub fn dispatch_compute_indirect(&self, buffer: &Buffer, index: usize) {
344 if self.shader.shader_type != ShaderType::Compute {
345 panic!("Only compute shaders could use the `dispatch_compute_indirect()` method.");
346 }
347 let bind = buffer.bind_to(BufferTarget::DispatchIndirectBuffer);
348 self.shader.glcore.glDispatchComputeIndirect(index * size_of::<DispatchIndirectCommand>());
349 bind.unbind();
350 }
351
352 pub fn setup_material_uniforms(&self, material: &dyn Material, prefix: Option<&str>, camel_case: bool) {
354 let glcore = &self.shader.glcore;
355 let shader_uniforms = self.shader.get_active_uniforms().unwrap();
356 let texture_names = material.get_names();
357 let mut active_texture = 0u32;
358 for name in texture_names.iter() {
359 let mut name_mod = String::new();
360 if let Some(prefix) = prefix {
361 name_mod.push_str(prefix);
362 }
363 if camel_case {
364 name_mod.push_str(&to_camel_case(name, prefix.is_some()));
365 } else {
366 name_mod.push_str(&name);
367 }
368 if let Some(_) = shader_uniforms.get(&name_mod) {
369 if let Some(texture) = material.get_by_name(&name) {
370 let location = self.shader.get_uniform_location(&name_mod);
371 if location == -1 {
372 continue;
373 }
374 match texture {
375 MaterialComponent::Texture(texture) => {
376 texture.set_active_unit(active_texture);
377 let bind = texture.bind();
378 glcore.glUniform1i(location, active_texture as i32);
379 bind.unbind();
380 active_texture += 1;
381 }
382 MaterialComponent::Color(color) => {
383 glcore.glUniform4f(location, color.x, color.y, color.z, color.w);
384 }
385 MaterialComponent::Luminance(lum) => {
386 glcore.glUniform1f(location, *lum);
387 }
388 }
389 }
390 }
391 }
392 }
393
394 pub fn unuse(self) {}
396}
397
398impl Drop for ShaderUse<'_> {
399 fn drop(&mut self) {
400 self.shader.glcore.glUseProgram(0)
401 }
402}
403
404impl Drop for Shader {
405 fn drop(&mut self) {
406 self.glcore.glDeleteProgram(self.program)
407 }
408}
409
410impl ShaderBinary {
411 pub fn new(format: u32, shader_type: ShaderType, binary: Vec<u8>) -> Self {
412 Self {
413 format,
414 shader_type,
415 binary,
416 }
417 }
418
419 pub fn load_from_file(path: &Path) -> Result<Self, ShaderBinaryLoadError> {
420 let config = bincode::config::standard()
421 .with_little_endian()
422 .with_fixed_int_encoding();
423 let mut file = std::fs::File::open(path)?;
424 Ok(bincode::decode_from_std_read(&mut file, config)?)
425 }
426
427 pub fn save_to_file(&self, path: &Path) -> Result<(), ShaderBinarySaveError> {
428 let config = bincode::config::standard()
429 .with_little_endian()
430 .with_fixed_int_encoding();
431 let mut file = std::fs::File::open(path)?;
432 bincode::encode_into_std_write(self, &mut file, config)?;
433 Ok(())
434 }
435}
436
437impl ShaderInputType {
438 pub fn is_float(&self) -> bool {
439 matches!(self, Self::Float | Self::Vec2 | Self::Vec3 | Self::Vec4 | Self::Mat2 | Self::Mat3 | Self::Mat4 | Self::Mat2x3 | Self::Mat2x4 | Self::Mat3x2 | Self::Mat3x4 | Self::Mat4x2 | Self::Mat4x3)
440 }
441
442 pub fn is_double(&self) -> bool {
443 matches!(self, Self::Double | Self::DVec2 | Self::DVec3 | Self::DVec4 | Self::DMat2 | Self::DMat3 | Self::DMat4 | Self::DMat2x3 | Self::DMat2x4 | Self::DMat3x2 | Self::DMat3x4 | Self::DMat4x2 | Self::DMat4x3)
444 }
445
446 pub fn is_integer(&self) -> bool {
447 matches!(self, Self::Int | Self::IVec2 | Self::IVec3 | Self::IVec4 | Self::UInt | Self::UVec2 | Self::UVec3 | Self::UVec4)
448 }
449
450 pub fn get_size_and_rows(&self) -> (u32, u32) {
451 match self {
452 Self::Float | Self::Double | Self::Int | Self::UInt => (1, 1),
453 Self::Vec2 | Self::DVec2 | Self::IVec2 | Self::UVec2 => (2, 1),
454 Self::Vec3 | Self::DVec3 | Self::IVec3 | Self::UVec3 => (3, 1),
455 Self::Vec4 | Self::DVec4 | Self::IVec4 | Self::UVec4 => (4, 1),
456 Self::Mat2 | Self::DMat2 => (2, 2),
457 Self::Mat3 | Self::DMat3 => (3, 3),
458 Self::Mat4 | Self::DMat4 => (4, 4),
459 Self::Mat2x3 | Self::DMat2x3 => (2, 3),
460 Self::Mat2x4 | Self::DMat2x4 => (2, 4),
461 Self::Mat3x2 | Self::DMat3x2 => (3, 2),
462 Self::Mat3x4 | Self::DMat3x4 => (3, 4),
463 Self::Mat4x2 | Self::DMat4x2 => (4, 2),
464 Self::Mat4x3 | Self::DMat4x3 => (4, 3),
465 }
466 }
467
468 pub fn get_base_type(&self) -> ShaderInputType {
469 match self {
470 Self::Float | Self::Vec2 | Self::Vec3 | Self::Vec4 | Self::Mat2 | Self::Mat3 | Self::Mat4 | Self::Mat2x3 | Self::Mat2x4 | Self::Mat3x2 | Self::Mat3x4 | Self::Mat4x2 | Self::Mat4x3 => Self::Float,
471 Self::Double | Self::DVec2 | Self::DVec3 | Self::DVec4 | Self::DMat2 | Self::DMat3 | Self::DMat4 | Self::DMat2x3 | Self::DMat2x4 | Self::DMat3x2 | Self::DMat3x4 | Self::DMat4x2 | Self::DMat4x3 => Self::Double,
472 Self::Int | Self::IVec2 | Self::IVec3 | Self::IVec4 => Self::Int,
473 Self::UInt | Self::UVec2 | Self::UVec3 | Self::UVec4 => Self::UInt,
474 }
475 }
476}
477
478impl ShaderInputVarType {
479 pub fn is_float(&self) -> bool {
480 self.type_.is_float()
481 }
482
483 pub fn is_double(&self) -> bool {
484 self.type_.is_double()
485 }
486
487 pub fn is_integer(&self) -> bool {
488 self.type_.is_integer()
489 }
490
491 pub fn get_size_and_rows(&self) -> (u32, u32) {
492 self.type_.get_size_and_rows()
493 }
494
495 pub fn get_type(&self) -> ShaderInputType {
496 self.type_
497 }
498
499 pub fn get_base_type(&self) -> ShaderInputType {
500 self.type_.get_base_type()
501 }
502}
503
504impl Debug for Shader {
505 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
506 f.debug_struct("Shader")
507 .field("program", &self.program)
508 .finish()
509 }
510}
511
512impl Debug for ShaderError {
513 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
514 match self {
515 Self::VSError(infolog) => write!(f, "Vertex Shader Error:\n{infolog}"),
516 Self::GSError(infolog) => write!(f, "Geometry Shader Error:\n{infolog}"),
517 Self::FSError(infolog) => write!(f, "Fragment Shader Error:\n{infolog}"),
518 Self::CSError(infolog) => write!(f, "Compute Shader Error:\n{infolog}"),
519 Self::LinkageError(infolog) => write!(f, "Shader Linkage Error:\n{infolog}"),
520 }
521 }
522}
523
524impl From<u32> for ShaderInputType {
525 fn from(val: u32) -> Self {
526 match val {
527 GL_FLOAT => Self::Float,
528 GL_FLOAT_VEC2 => Self::Vec2,
529 GL_FLOAT_VEC3 => Self::Vec3,
530 GL_FLOAT_VEC4 => Self::Vec4,
531 GL_FLOAT_MAT2 => Self::Mat2,
532 GL_FLOAT_MAT3 => Self::Mat3,
533 GL_FLOAT_MAT4 => Self::Mat4,
534 GL_FLOAT_MAT2x3 => Self::Mat2x3,
535 GL_FLOAT_MAT2x4 => Self::Mat2x4,
536 GL_FLOAT_MAT3x2 => Self::Mat3x2,
537 GL_FLOAT_MAT3x4 => Self::Mat3x4,
538 GL_FLOAT_MAT4x2 => Self::Mat4x2,
539 GL_FLOAT_MAT4x3 => Self::Mat4x3,
540 GL_INT => Self::Int,
541 GL_INT_VEC2 => Self::IVec2,
542 GL_INT_VEC3 => Self::IVec3,
543 GL_INT_VEC4 => Self::IVec4,
544 GL_UNSIGNED_INT => Self::UInt,
545 GL_UNSIGNED_INT_VEC2 => Self::UVec2,
546 GL_UNSIGNED_INT_VEC3 => Self::UVec3,
547 GL_UNSIGNED_INT_VEC4 => Self::UVec4,
548 GL_DOUBLE => Self::Double,
549 GL_DOUBLE_VEC2 => Self::DVec2,
550 GL_DOUBLE_VEC3 => Self::DVec3,
551 GL_DOUBLE_VEC4 => Self::DVec4,
552 GL_DOUBLE_MAT2 => Self::DMat2,
553 GL_DOUBLE_MAT3 => Self::DMat3,
554 GL_DOUBLE_MAT4 => Self::DMat4,
555 GL_DOUBLE_MAT2x3 => Self::DMat2x3,
556 GL_DOUBLE_MAT2x4 => Self::DMat2x4,
557 GL_DOUBLE_MAT3x2 => Self::DMat3x2,
558 GL_DOUBLE_MAT3x4 => Self::DMat3x4,
559 GL_DOUBLE_MAT4x2 => Self::DMat4x2,
560 GL_DOUBLE_MAT4x3 => Self::DMat4x3,
561 _ => panic!("Invalid value {val} of `ShaderInputType`"),
562 }
563 }
564}
565
566impl Debug for ShaderInputType {
567 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
568 match self {
569 Self::Float => write!(f, "float"),
570 Self::Vec2 => write!(f, "vec2"),
571 Self::Vec3 => write!(f, "vec3"),
572 Self::Vec4 => write!(f, "vec4"),
573 Self::Mat2 => write!(f, "mat2"),
574 Self::Mat3 => write!(f, "mat3"),
575 Self::Mat4 => write!(f, "mat4"),
576 Self::Mat2x3 => write!(f, "mat2x3"),
577 Self::Mat2x4 => write!(f, "mat2x4"),
578 Self::Mat3x2 => write!(f, "mat3x2"),
579 Self::Mat3x4 => write!(f, "mat3x4"),
580 Self::Mat4x2 => write!(f, "mat4x2"),
581 Self::Mat4x3 => write!(f, "mat4x3"),
582 Self::Int => write!(f, "int"),
583 Self::IVec2 => write!(f, "ivec2"),
584 Self::IVec3 => write!(f, "ivec3"),
585 Self::IVec4 => write!(f, "ivec4"),
586 Self::UInt => write!(f, "uint"),
587 Self::UVec2 => write!(f, "uvec2"),
588 Self::UVec3 => write!(f, "uvec3"),
589 Self::UVec4 => write!(f, "uvec4"),
590 Self::Double => write!(f, "double"),
591 Self::DVec2 => write!(f, "dvec2"),
592 Self::DVec3 => write!(f, "dvec3"),
593 Self::DVec4 => write!(f, "dvec4"),
594 Self::DMat2 => write!(f, "dmat2"),
595 Self::DMat3 => write!(f, "dmat3"),
596 Self::DMat4 => write!(f, "dmat4"),
597 Self::DMat2x3 => write!(f, "dmat2x3"),
598 Self::DMat2x4 => write!(f, "dmat2x4"),
599 Self::DMat3x2 => write!(f, "dmat3x2"),
600 Self::DMat3x4 => write!(f, "dmat3x4"),
601 Self::DMat4x2 => write!(f, "dmat4x2"),
602 Self::DMat4x3 => write!(f, "dmat4x3"),
603 }
604 }
605}
606
607impl Display for ShaderInputType {
608 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
609 <Self as Debug>::fmt(self, f)
610 }
611}
612
613impl From<std::io::Error> for ShaderBinaryLoadError {
614 fn from(err: std::io::Error) -> Self {
615 Self::IOError(err)
616 }
617}
618
619impl From<bincode::error::DecodeError> for ShaderBinaryLoadError {
620 fn from(err: bincode::error::DecodeError) -> Self {
621 Self::DecodeError(err)
622 }
623}
624
625impl From<std::io::Error> for ShaderBinarySaveError {
626 fn from(err: std::io::Error) -> Self {
627 Self::IOError(err)
628 }
629}
630
631impl From<bincode::error::EncodeError> for ShaderBinarySaveError {
632 fn from(err: bincode::error::EncodeError) -> Self {
633 Self::EncodeError(err)
634 }
635}