feo_oop_engine/shaders/
mod.rs

1//! GLSL Shaders
2
3/// vertex shader that parses a model
4pub(crate) mod vs_draw {
5    use std::{sync::Arc, borrow::Cow, ffi::CStr};
6    use vulkano::{pipeline::shader::{ShaderModule, GraphicsShaderType, ShaderInterfaceDef, ShaderInterfaceDefEntry, GraphicsEntryPoint}, OomError, device::Device, format::Format, descriptor::{descriptor::{ShaderStages, DescriptorDesc, DescriptorDescTy, DescriptorBufferDesc}, pipeline_layout::{PipelineLayoutDesc, PipelineLayoutDescPcRange}}};
7
8    const SPIRV: &'static [u8] = &*include_bytes!("./spv_precompiles/vs_draw.spv");
9
10    pub mod ty {
11        #[repr(C)]
12        pub struct Camera{
13            pub to_view: [[f32; 4]; 4], // ident space to view space
14            pub view_to_screen: [[f32; 4]; 4], // view space to screen space
15        }
16        #[repr(C)]
17        pub struct World{
18            pub object_to: [[f32; 4]; 4], // ident space to view space
19        }
20    }
21    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
22    pub struct VertInput;
23
24    unsafe impl ShaderInterfaceDef for VertInput {
25        type Iter = VertInputIter;
26
27        fn elements(&self) -> VertInputIter {
28            VertInputIter(0)
29        }
30    }
31
32    #[derive(Debug, Copy, Clone)]
33    pub struct VertInputIter(u16);
34
35    impl Iterator for VertInputIter {
36        type Item = ShaderInterfaceDefEntry;
37
38        #[inline]
39        fn next(&mut self) -> Option<Self::Item> {
40            if self.0 == 2 {
41                self.0 += 1;
42                return Some(ShaderInterfaceDefEntry {
43                    location: 0..1,
44                    format: Format::R32G32B32Sfloat,
45                    name: Some(Cow::Borrowed("position")),
46                });
47            } else if self.0 == 1 {
48                self.0 += 1;
49                return Some(ShaderInterfaceDefEntry {
50                    location: 1..2,
51                    format: Format::R32G32B32Sfloat,
52                    name: Some(Cow::Borrowed("normal")),
53                });
54            } else if self.0 == 0 {
55                self.0 += 1;
56                return Some(ShaderInterfaceDefEntry {
57                    location: 2..3,
58                    format: Format::R32G32Sfloat,
59                    name: Some(Cow::Borrowed("texture_index")),
60                });
61            }
62            None
63        }
64
65        #[inline]
66        fn size_hint(&self) -> (usize, Option<usize>) {
67            let len = (3 - self.0) as usize;
68            (len, Some(len))
69        }
70    }
71
72    impl ExactSizeIterator for VertInputIter {}
73
74    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
75    pub struct VertOutput;
76
77    unsafe impl ShaderInterfaceDef for VertOutput {
78        type Iter = VertOutputIter;
79
80        fn elements(&self) -> VertOutputIter {
81            VertOutputIter(0)
82        }
83    }
84
85    #[derive(Debug, Copy, Clone)]
86    pub struct VertOutputIter(u16);
87
88    impl Iterator for VertOutputIter {
89        type Item = ShaderInterfaceDefEntry;
90
91        #[inline]
92        fn next(&mut self) -> Option<Self::Item> {
93            if self.0 == 2 {
94                self.0 += 1;
95                return Some(ShaderInterfaceDefEntry {
96                    location: 0..1,
97                    format: Format::R32G32B32Sfloat,
98                    name: Some(Cow::Borrowed("v_normal")),
99                });
100            } else if self.0 == 1 {
101                self.0 += 1;
102                return Some(ShaderInterfaceDefEntry {
103                    location: 1..2,
104                    format: Format::R32G32Sfloat,
105                    name: Some(Cow::Borrowed("v_texture_index")),
106                });
107            } else if self.0 == 0 {
108                self.0 += 1;
109                return Some(ShaderInterfaceDefEntry {
110                    location: 2..3,
111                    format: Format::R32G32Sfloat,
112                    name: Some(Cow::Borrowed("v_camspace_xy")),
113                });
114            }
115            None
116        }
117
118        #[inline]
119        fn size_hint(&self) -> (usize, Option<usize>) {
120            let len = (3 - self.0) as usize;
121            (len, Some(len))
122        }
123    }
124
125    impl ExactSizeIterator for VertOutputIter {}
126
127    // This structure describes layout of this stage.
128    #[derive(Debug, Copy, Clone)]
129    pub struct VertLayout(ShaderStages);
130    unsafe impl PipelineLayoutDesc for VertLayout {
131        // Number of descriptor sets it takes.
132        fn num_sets(&self) -> usize {
133            2
134        }
135        // Number of entries (bindings) in each set.
136        fn num_bindings_in_set(&self, _set: usize) -> Option<usize> {
137            Some(1)
138        }
139        // Descriptor descriptions.
140        fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
141            if set == 0 && binding == 0 {
142                Some(DescriptorDesc {
143                    ty: DescriptorDescTy::Buffer(
144                        DescriptorBufferDesc{
145                            dynamic: None,
146                            storage: false
147                        }
148                    ),
149                    array_count: 1,
150                    stages: ShaderStages{
151                        vertex: true,
152                        ..ShaderStages::none()
153                    },
154                    readonly: true
155                })
156            } else if set == 1 && binding == 0 {
157                Some(DescriptorDesc {
158                    ty: DescriptorDescTy::Buffer(
159                        DescriptorBufferDesc{
160                            dynamic: None,
161                            storage: false
162                        }
163                    ),
164                    array_count: 1,
165                    stages: ShaderStages{
166                        vertex: true,
167                        ..ShaderStages::none()
168                    },
169                    readonly: true
170                })
171            } else {
172                None
173            }
174        }
175        // Number of push constants ranges (think: number of push constants).
176        fn num_push_constants_ranges(&self) -> usize {
177            0
178        }
179        // Each push constant range in memory.
180        fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> {
181            None
182        }
183    }
184    pub struct Shader {
185        module: Arc<ShaderModule>
186    }
187    impl Shader {
188        pub fn load(device: Arc<Device>) -> Result<Self, OomError> {
189            Ok(Shader{ module: unsafe { ShaderModule::new(device.clone(), &SPIRV) }? })
190        }
191        pub fn main_entry_point(&self) -> GraphicsEntryPoint<(), VertInput, VertOutput, VertLayout> {
192            unsafe{ 
193                self.module.graphics_entry_point(
194                    CStr::from_bytes_with_nul_unchecked(b"main\0"),
195                    VertInput,
196                    VertOutput,
197                    VertLayout(ShaderStages {
198                        vertex: true,
199                        ..ShaderStages::none()
200                    }),
201                    GraphicsShaderType::Vertex,
202                )
203            }
204        }
205    }
206
207    // vulkano_shaders::shader! {
208    //     ty: "vertex",
209    //     path: "./src/shaders/draw/vs_draw.vert"
210    // }
211}
212
213/// fragment shader that writes out diffuse color and albedo
214pub(crate) mod fs_draw {
215    use std::{borrow::Cow, sync::Arc, ffi::CStr};
216    use vulkano::{pipeline::shader::{ShaderInterfaceDef, ShaderInterfaceDefEntry, ShaderModule, GraphicsEntryPoint, GraphicsShaderType}, format::Format, descriptor::{descriptor::{ShaderStages, DescriptorDesc, DescriptorDescTy, DescriptorBufferDesc, DescriptorImageDesc, DescriptorImageDescDimensions, DescriptorImageDescArray}, pipeline_layout::{PipelineLayoutDesc, PipelineLayoutDescPcRange}}, device::Device, OomError};
217
218    const SPIRV: &'static [u8] = &*include_bytes!("./spv_precompiles/fs_draw.spv");
219    
220    pub mod ty {
221        #[repr(C)]
222        #[derive(Clone)]
223        pub struct Material {// diffuse reflectance
224            // [0..3]: color 
225            // [3]:
226            //   0 -> [0..3] only
227            //   1 -> map * [0..3]
228            // //   2 -> map_alpha // TODO: implement
229            pub diffuse: [f32; 4],
230        
231            // ambient reflectance
232            // [0..3]: color 
233            // [3]:
234            //   0 -> none,
235            //   1 -> [0..3] only,
236            //   2 -> map * [0..3],
237            // //   3 -> map_alpha // TODO: implement
238            pub ambient: [f32; 4],
239        
240            // specular reflectance
241            // [0..3]: specular color
242            // [3]: size of specular highlights / shine
243            //    0 -> dull unfocused -> no specular anything
244            //    ..
245            //    1000 -> shiny focused
246            //    1001 -> specular highlight size map only
247            //    n -> specular highlight size map + (n - 1001) where map + (n - 1001) <= 1000   
248            //    2001 -> ...
249            //    sign:
250            //      + -> no specular map just [0..3]
251            //      - -> specular map * [0..3]
252            pub specular: [f32; 4],
253        
254            // // emissive color
255            // // |4th value|: 
256            // //   0 -> no emissive anything
257            // //   ..
258            // //   1000 -> high
259            // // 4th value sign:
260            // //   + -> no mask map
261            // //   - -> mask map
262            // vec4 emissive_color,
263        
264            // [0]: alpha transparency:
265            //     0 -> transparent 
266            //     ..
267            //     1 -> opaque
268            // [1..2]: index of refraction: // TODO: implement
269            //   [1]: 
270            //     0..1000
271            //   [2]: // redefine
272            //     0 -> no effect
273            //     1 -> no effect
274            // [2]: illumination model:
275            //     0 -> Color on and Ambient off
276            //     1 -> Color on and Ambient on
277            //     2 -> Highlight on
278            //     3 -> Reflection on and Ray trace on
279            //     4 -> Transparency: Glass on
280            //     Reflection: Ray trace on
281            //     5 -> Reflection: Fresnel on and Ray trace on
282            //     6 -> Transparency: Refraction on
283            //     Reflection: Fresnel off and Ray trace on
284            //     7 -> Transparency: Refraction on
285            //     Reflection: Fresnel on and Ray trace on
286            //     8 -> Reflection on and Ray trace off
287            //     9 -> Transparency: Glass on
288            //     Reflection: Ray trace off
289            //     10 -> Casts shadows onto invisible surfaces
290            pub other: [f32; 4],
291        }
292    }
293
294    // Same as with our vertex shader, but for fragment one instead.
295    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
296    pub struct FragInput;
297    unsafe impl ShaderInterfaceDef for FragInput {
298        type Iter = FragInputIter;
299
300        fn elements(&self) -> FragInputIter {
301            FragInputIter(0)
302        }
303    }
304    #[derive(Debug, Copy, Clone)]
305    pub struct FragInputIter(u16);
306
307    impl Iterator for FragInputIter {
308        type Item = ShaderInterfaceDefEntry;
309
310        #[inline]
311        fn next(&mut self) -> Option<Self::Item> {
312            if self.0 == 2 {
313                self.0 += 1;
314                return Some(ShaderInterfaceDefEntry {
315                    location: 2..3,
316                    format: Format::R32G32Sfloat,
317                    name: Some(Cow::Borrowed("v_camspace_xy")),
318                });
319            } else if self.0 == 1 {
320                self.0 += 1;
321                return Some(ShaderInterfaceDefEntry {
322                    location: 1..2,
323                    format: Format::R32G32Sfloat,
324                    name: Some(Cow::Borrowed("v_texture_index")),
325                });
326            } else if self.0 == 0 {
327                self.0 += 1;
328                return Some(ShaderInterfaceDefEntry {
329                    location: 0..1,
330                    format: Format::R32G32B32Sfloat,
331                    name: Some(Cow::Borrowed("v_normal")),
332                });
333            }
334            None
335        }
336
337        #[inline]
338        fn size_hint(&self) -> (usize, Option<usize>) {
339            let len = (3 - self.0) as usize;
340            (len, Some(len))
341        }
342    }
343
344    impl ExactSizeIterator for FragInputIter {}
345
346    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
347    pub struct FragOutput;
348    unsafe impl ShaderInterfaceDef for FragOutput {
349        type Iter = FragOutputIter;
350
351        fn elements(&self) -> FragOutputIter {
352            FragOutputIter(0)
353        }
354    }
355
356    #[derive(Debug, Copy, Clone)]
357    pub struct FragOutputIter(u16);
358
359    impl Iterator for FragOutputIter {
360        type Item = ShaderInterfaceDefEntry;
361
362        #[inline]
363        fn next(&mut self) -> Option<Self::Item> {
364            if self.0 == 3 {
365                self.0 += 1;
366                return Some(ShaderInterfaceDefEntry {
367                    location: 0..1,
368                    format: Format::R32G32B32A32Sfloat,
369                    name: Some(Cow::Borrowed("f_normals")),
370                });
371            } else if self.0 == 2 {
372                self.0 += 1;
373                return Some(ShaderInterfaceDefEntry {
374                    location: 1..2,
375                    format: Format::R32G32B32A32Sfloat,
376                    name: Some(Cow::Borrowed("f_diffuse")),
377                });
378            } else if self.0 == 1 {
379                self.0 += 1;
380                return Some(ShaderInterfaceDefEntry {
381                    location: 2..3,
382                    format: Format::R32G32B32A32Sfloat,
383                    name: Some(Cow::Borrowed("f_ambient")),
384                });
385            } else if self.0 == 0 {
386                self.0 += 1;
387                return Some(ShaderInterfaceDefEntry {
388                    location: 3..4,
389                    format: Format::R32G32B32A32Sfloat,
390                    name: Some(Cow::Borrowed("f_specular")),
391                });
392            }
393            None
394        }
395        #[inline]
396        fn size_hint(&self) -> (usize, Option<usize>) {
397            let len = (4 - self.0) as usize;
398            (len, Some(len))
399        }
400    }
401
402    impl ExactSizeIterator for FragOutputIter {}
403
404    // Layout same as with vertex shader.
405    #[derive(Debug, Copy, Clone)]
406    pub struct FragLayout(ShaderStages);
407    unsafe impl PipelineLayoutDesc for FragLayout {
408        fn num_sets(&self) -> usize {
409            3
410        }
411        fn num_bindings_in_set(&self, set: usize) -> Option<usize> {
412            if set == 2 {
413                Some(5)
414            } else {
415                None
416            }
417        }
418        fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
419            if set == 2 && binding == 0 {
420                return Some(DescriptorDesc {
421                    ty: DescriptorDescTy::Buffer(
422                        DescriptorBufferDesc{
423                            dynamic: None,
424                            storage: false
425                        }
426                    ),
427                    array_count: 1,
428                    stages: ShaderStages{
429                        fragment: true,
430                        ..ShaderStages::none()
431                    },
432                    readonly: false
433                });
434            } else if set == 2 && (binding >= 1 || binding <= 4) {
435                return Some(DescriptorDesc {
436                    ty: DescriptorDescTy::CombinedImageSampler(DescriptorImageDesc{
437                        sampled: true,
438                        dimensions: DescriptorImageDescDimensions::TwoDimensional,
439                        format: None,
440                        multisampled: false,
441                        array_layers: DescriptorImageDescArray::NonArrayed,
442                    }),
443                    array_count: 1,
444                    stages: ShaderStages{
445                        fragment: true,
446                        ..ShaderStages::none()
447                    },
448                    readonly: true
449                });
450            }
451            None
452        }
453        fn num_push_constants_ranges(&self) -> usize {
454            0
455        }
456        fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> {
457            None
458        }
459    }
460
461    pub struct Shader {
462        module: Arc<ShaderModule>
463    }
464    impl Shader {
465        pub fn load(device: Arc<Device>) -> Result<Self, OomError> {
466            Ok(Shader{ module: unsafe { ShaderModule::new(device.clone(), &SPIRV) }? })
467        }
468        pub fn main_entry_point(&self) -> GraphicsEntryPoint<(), FragInput, FragOutput, FragLayout> {
469            unsafe{ 
470                self.module.graphics_entry_point(
471                    CStr::from_bytes_with_nul_unchecked(b"main\0"),
472                    FragInput,
473                    FragOutput,
474                    FragLayout(ShaderStages {
475                        fragment: true,
476                        ..ShaderStages::none()
477                    }),
478                    GraphicsShaderType::Fragment,
479                )
480            }
481        }
482    }
483
484    // vulkano_shaders::shader! {
485    //     ty: "fragment",
486    //     path: "./src/shaders/draw/fs_draw.frag"
487    // }
488}
489
490/// vertex shader for light systems
491pub(crate) mod vs_lighting {
492    use std::{sync::Arc, borrow::Cow, ffi::CStr};
493    use vulkano::{pipeline::shader::{ShaderModule, GraphicsShaderType, ShaderInterfaceDef, ShaderInterfaceDefEntry, GraphicsEntryPoint}, OomError, device::Device, format::Format, descriptor::{descriptor::{ShaderStages, DescriptorDesc}, pipeline_layout::{PipelineLayoutDesc, PipelineLayoutDescPcRange}}};
494
495    const SPIRV: &'static [u8] = &*include_bytes!("./spv_precompiles/vs_lighting.spv");
496
497    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
498    pub struct VertInput;
499
500    unsafe impl ShaderInterfaceDef for VertInput {
501        type Iter = VertInputIter;
502
503        fn elements(&self) -> VertInputIter {
504            VertInputIter(0)
505        }
506    }
507
508    #[derive(Debug, Copy, Clone)]
509    pub struct VertInputIter(u16);
510
511    impl Iterator for VertInputIter {
512        type Item = ShaderInterfaceDefEntry;
513
514        #[inline]
515        fn next(&mut self) -> Option<Self::Item> {
516            if self.0 == 0 {
517                self.0 += 1;
518                return Some(ShaderInterfaceDefEntry {
519                    location: 0..1,
520                    format: Format::R32G32Sfloat,
521                    name: Some(Cow::Borrowed("position")),
522                });
523            }
524            None
525        }
526
527        #[inline]
528        fn size_hint(&self) -> (usize, Option<usize>) {
529            let len = (1 - self.0) as usize;
530            (len, Some(len))
531        }
532    }
533
534    impl ExactSizeIterator for VertInputIter {}
535
536    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
537    pub struct VertOutput;
538
539    unsafe impl ShaderInterfaceDef for VertOutput {
540        type Iter = VertOutputIter;
541
542        fn elements(&self) -> VertOutputIter {
543            VertOutputIter(0)
544        }
545    }
546
547    #[derive(Debug, Copy, Clone)]
548    pub struct VertOutputIter(u16);
549
550    impl Iterator for VertOutputIter {
551        type Item = ShaderInterfaceDefEntry;
552
553        #[inline]
554        fn next(&mut self) -> Option<Self::Item> {
555            None
556        }
557
558        #[inline]
559        fn size_hint(&self) -> (usize, Option<usize>) {
560            (0, Some(0))
561        }
562    }
563
564    impl ExactSizeIterator for VertOutputIter {}
565
566    // This structure describes layout of this stage.
567    #[derive(Debug, Copy, Clone)]
568    pub struct VertLayout(ShaderStages);
569    unsafe impl PipelineLayoutDesc for VertLayout {
570        // Number of descriptor sets it takes.
571        fn num_sets(&self) -> usize {
572            0
573        }
574        // Number of entries (bindings) in each set.
575        fn num_bindings_in_set(&self, _set: usize) -> Option<usize> {
576            None
577        }
578        // Descriptor descriptions.
579        fn descriptor(&self, _set: usize, _binding: usize) -> Option<DescriptorDesc> {
580            None
581        }
582        // Number of push constants ranges (think: number of push constants).
583        fn num_push_constants_ranges(&self) -> usize {
584            0
585        }
586        // Each push constant range in memory.
587        fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> {
588            None
589        }
590    }
591    pub struct Shader {
592        module: Arc<ShaderModule>
593    }
594    impl Shader {
595        pub fn load(device: Arc<Device>) -> Result<Self, OomError> {
596            Ok(Shader{ module: unsafe { ShaderModule::new(device.clone(), &SPIRV) }? })
597        }
598        pub fn main_entry_point(&self) -> GraphicsEntryPoint<(), VertInput, VertOutput, VertLayout> {
599            unsafe{ 
600                self.module.graphics_entry_point(
601                    CStr::from_bytes_with_nul_unchecked(b"main\0"),
602                    VertInput,
603                    VertOutput,
604                    VertLayout(ShaderStages {
605                        vertex: true,
606                        ..ShaderStages::none()
607                    }),
608                    GraphicsShaderType::Vertex,
609                )
610            }
611        }
612    }
613
614    // vulkano_shaders::shader! {
615    //     ty: "vertex",
616    //     path: "./src/shaders/lighting/vs_lighting.vert"
617    // }
618}
619
620/// fragment shader for a point light
621pub(crate) mod fs_lighting_point {
622    use std::{borrow::Cow, sync::Arc, ffi::CStr};
623    use vulkano::{pipeline::shader::{ShaderInterfaceDef, ShaderInterfaceDefEntry, ShaderModule, GraphicsEntryPoint, GraphicsShaderType}, format::Format, descriptor::{descriptor::{ShaderStages, DescriptorDesc, DescriptorDescTy, DescriptorImageDescArray}, pipeline_layout::{PipelineLayoutDesc, PipelineLayoutDescPcRange}}, device::Device, OomError};
624
625    const SPIRV: &'static [u8] = &*include_bytes!("./spv_precompiles/fs_lighting_point.spv");
626    
627    pub mod ty {
628        #[repr(C)]
629        pub struct PushConstants {
630            // Screen space to camera space projection matrix
631            pub screen_to_camera: [[f32; 4]; 4],
632            // The point lights color
633            pub color: [f32; 4],
634            // The position of the light in camera space
635            pub position_camera_space: [f32; 4]
636        }
637    }
638
639    // Same as with our vertex shader, but for fragment one instead.
640    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
641    pub struct FragInput;
642    unsafe impl ShaderInterfaceDef for FragInput {
643        type Iter = FragInputIter;
644
645        fn elements(&self) -> FragInputIter {
646            FragInputIter(0)
647        }
648    }
649    #[derive(Debug, Copy, Clone)]
650    pub struct FragInputIter(u16);
651
652    impl Iterator for FragInputIter {
653        type Item = ShaderInterfaceDefEntry;
654
655        #[inline]
656        fn next(&mut self) -> Option<Self::Item> {
657            None
658        }
659
660        #[inline]
661        fn size_hint(&self) -> (usize, Option<usize>) {
662            (0, Some(0))
663        }
664    }
665
666    impl ExactSizeIterator for FragInputIter {}
667
668    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
669    pub struct FragOutput;
670    unsafe impl ShaderInterfaceDef for FragOutput {
671        type Iter = FragOutputIter;
672
673        fn elements(&self) -> FragOutputIter {
674            FragOutputIter(0)
675        }
676    }
677
678    #[derive(Debug, Copy, Clone)]
679    pub struct FragOutputIter(u16);
680
681    impl Iterator for FragOutputIter {
682        type Item = ShaderInterfaceDefEntry;
683
684        #[inline]
685        fn next(&mut self) -> Option<Self::Item> {
686            if self.0 == 0 {
687                self.0 += 1;
688                return Some(ShaderInterfaceDefEntry {
689                    location: 0..1,
690                    format: Format::R32G32B32A32Sfloat,
691                    name: Some(Cow::Borrowed("f_color")),
692                });
693            }
694            None
695        }
696        #[inline]
697        fn size_hint(&self) -> (usize, Option<usize>) {
698            let len = (1 - self.0) as usize;
699            (len, Some(len))
700        }
701    }
702
703    impl ExactSizeIterator for FragOutputIter {}
704
705    // Layout same as with vertex shader.
706    #[derive(Debug, Copy, Clone)]
707    pub struct FragLayout(ShaderStages);
708    unsafe impl PipelineLayoutDesc for FragLayout {
709        fn num_sets(&self) -> usize {
710            1
711        }
712        fn num_bindings_in_set(&self, _set: usize) -> Option<usize> {
713            Some(4)
714        }
715        fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
716            if set == 0 && binding == 0 {
717                return Some(DescriptorDesc {
718                    ty: DescriptorDescTy::InputAttachment{
719                        multisampled: false,
720                        array_layers: DescriptorImageDescArray::NonArrayed,
721                    },
722                    array_count: 1,
723                    stages: ShaderStages{
724                        fragment: true,
725                        ..ShaderStages::none()
726                    },
727                    readonly: true
728                });
729            } else if set == 0 && binding <= 3 {
730                return Some(DescriptorDesc {
731                    ty: DescriptorDescTy::InputAttachment{
732                        multisampled: false,
733                        array_layers: DescriptorImageDescArray::NonArrayed,
734                    },
735                    array_count: 1,
736                    stages: ShaderStages{
737                        fragment: true,
738                        ..ShaderStages::none()
739                    },
740                    readonly: true
741                });
742            } else {
743                return None;
744            }
745        }
746        fn num_push_constants_ranges(&self) -> usize {
747            1
748        }
749        fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> {
750            Some(
751                PipelineLayoutDescPcRange{
752                    offset: 0,
753                    size: 96,
754                    stages: ShaderStages{
755                        fragment: true,
756                        ..ShaderStages::none()
757                    },
758                }
759            )
760        }
761    }
762
763    pub struct Shader {
764        module: Arc<ShaderModule>
765    }
766    impl Shader {
767        pub fn load(device: Arc<Device>) -> Result<Self, OomError> {
768            Ok(Shader{ module: unsafe { ShaderModule::new(device.clone(), &SPIRV) }? })
769        }
770        pub fn main_entry_point(&self) -> GraphicsEntryPoint<(), FragInput, FragOutput, FragLayout> {
771            unsafe{ 
772                self.module.graphics_entry_point(
773                    CStr::from_bytes_with_nul_unchecked(b"main\0"),
774                    FragInput,
775                    FragOutput,
776                    FragLayout(ShaderStages {
777                        fragment: true,
778                        ..ShaderStages::none()
779                    }),
780                    GraphicsShaderType::Fragment,
781                )
782            }
783        }
784    }
785
786    // vulkano_shaders::shader! {
787    //     ty: "fragment",
788    //     path: "./src/shaders/lighting/fs_lighting_point.frag"
789    // }
790}
791
792/// fragment shader for directional lighting
793pub(crate) mod fs_lighting_directional {
794    use std::{borrow::Cow, sync::Arc, ffi::CStr};
795    use vulkano::{pipeline::shader::{ShaderInterfaceDef, ShaderInterfaceDefEntry, ShaderModule, GraphicsEntryPoint, GraphicsShaderType}, format::Format, descriptor::{descriptor::{ShaderStages, DescriptorDesc, DescriptorDescTy, DescriptorImageDescArray}, pipeline_layout::{PipelineLayoutDesc, PipelineLayoutDescPcRange}}, device::Device, OomError};
796
797    const SPIRV: &'static [u8] = &*include_bytes!("./spv_precompiles/fs_lighting_directional.spv");
798
799    pub mod ty {
800        #[repr(C)]
801        pub struct PushConstants {
802            // The color of the directional light
803            pub color: [f32; 4],
804            // The direction in which the directional light is shining
805            pub direction: [f32; 4]
806        }
807    }
808
809    // Same as with our vertex shader, but for fragment one instead.
810    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
811    pub struct FragInput;
812    unsafe impl ShaderInterfaceDef for FragInput {
813        type Iter = FragInputIter;
814
815        fn elements(&self) -> FragInputIter {
816            FragInputIter(0)
817        }
818    }
819    #[derive(Debug, Copy, Clone)]
820    pub struct FragInputIter(u16);
821
822    impl Iterator for FragInputIter {
823        type Item = ShaderInterfaceDefEntry;
824
825        #[inline]
826        fn next(&mut self) -> Option<Self::Item> {
827            None
828        }
829
830        #[inline]
831        fn size_hint(&self) -> (usize, Option<usize>) {
832            (0, Some(0))
833        }
834    }
835
836    impl ExactSizeIterator for FragInputIter {}
837
838    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
839    pub struct FragOutput;
840    unsafe impl ShaderInterfaceDef for FragOutput {
841        type Iter = FragOutputIter;
842
843        fn elements(&self) -> FragOutputIter {
844            FragOutputIter(0)
845        }
846    }
847
848    #[derive(Debug, Copy, Clone)]
849    pub struct FragOutputIter(u16);
850
851    impl Iterator for FragOutputIter {
852        type Item = ShaderInterfaceDefEntry;
853
854        #[inline]
855        fn next(&mut self) -> Option<Self::Item> {
856            if self.0 == 0 {
857                self.0 += 1;
858                return Some(ShaderInterfaceDefEntry {
859                    location: 0..1,
860                    format: Format::R32G32B32A32Sfloat,
861                    name: Some(Cow::Borrowed("f_color")),
862                });
863            }
864            None
865        }
866        #[inline]
867        fn size_hint(&self) -> (usize, Option<usize>) {
868            let len = (1 - self.0) as usize;
869            (len, Some(len))
870        }
871    }
872
873    impl ExactSizeIterator for FragOutputIter {}
874
875    // Layout same as with vertex shader.
876    #[derive(Debug, Copy, Clone)]
877    pub struct FragLayout(ShaderStages);
878    unsafe impl PipelineLayoutDesc for FragLayout {
879        fn num_sets(&self) -> usize {
880            1
881        }
882        fn num_bindings_in_set(&self, _set: usize) -> Option<usize> {
883            Some(2)
884        }
885        fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
886            if set == 0 && binding == 0 {
887                return Some(DescriptorDesc {
888                    ty: DescriptorDescTy::InputAttachment{
889                        multisampled: false,
890                        array_layers: DescriptorImageDescArray::NonArrayed,
891                    },
892                    array_count: 1,
893                    stages: ShaderStages{
894                        fragment: true,
895                        ..ShaderStages::none()
896                    },
897                    readonly: true
898                });
899            } else if set == 0 && binding == 1 {
900                return Some(DescriptorDesc {
901                    ty: DescriptorDescTy::InputAttachment{
902                        multisampled: false,
903                        array_layers: DescriptorImageDescArray::NonArrayed,
904                    },
905                    array_count: 1,
906                    stages: ShaderStages{
907                        fragment: true,
908                        ..ShaderStages::none()
909                    },
910                    readonly: true
911                });
912            } else {
913                return None;
914            }
915        }
916        fn num_push_constants_ranges(&self) -> usize {
917            1
918        }
919        fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> {
920            Some(
921                PipelineLayoutDescPcRange{
922                    offset: 0,
923                    size: 32,
924                    stages: ShaderStages{
925                        fragment: true,
926                        ..ShaderStages::none()
927                    },
928                }
929            )
930        }
931    }
932
933    pub struct Shader {
934        module: Arc<ShaderModule>
935    }
936    impl Shader {
937        pub fn load(device: Arc<Device>) -> Result<Self, OomError> {
938            Ok(Shader{ module: unsafe { ShaderModule::new(device.clone(), &SPIRV) }? })
939        }
940        pub fn main_entry_point(&self) -> GraphicsEntryPoint<(), FragInput, FragOutput, FragLayout> {
941            unsafe{ 
942                self.module.graphics_entry_point(
943                    CStr::from_bytes_with_nul_unchecked(b"main\0"),
944                    FragInput,
945                    FragOutput,
946                    FragLayout(ShaderStages {
947                        fragment: true,
948                        ..ShaderStages::none()
949                    }),
950                    GraphicsShaderType::Fragment,
951                )
952            }
953        }
954    }
955
956    // vulkano_shaders::shader! {
957    //     ty: "fragment",
958    //     path: "./src/shaders/lighting/fs_lighting_directional.frag"
959    // }
960}
961
962/// fragment shader for ambient lighting 
963pub(crate) mod fs_lighting_ambient {
964    use std::{borrow::Cow, sync::Arc, ffi::CStr};
965    use vulkano::{pipeline::shader::{ShaderInterfaceDef, ShaderInterfaceDefEntry, ShaderModule, GraphicsEntryPoint, GraphicsShaderType}, format::Format, descriptor::{descriptor::{ShaderStages, DescriptorDesc, DescriptorDescTy, DescriptorImageDescArray}, pipeline_layout::{PipelineLayoutDesc, PipelineLayoutDescPcRange}}, device::Device, OomError};
966
967    const SPIRV: &'static [u8] = &*include_bytes!("./spv_precompiles/fs_lighting_ambient.spv");
968    
969    pub mod ty {
970        #[repr(C)]
971        pub struct PushConstants {
972            // The color of the ambient light
973            pub color: [f32; 4]
974        }
975    }
976
977    // Same as with our vertex shader, but for fragment one instead.
978    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
979    pub struct FragInput;
980    unsafe impl ShaderInterfaceDef for FragInput {
981        type Iter = FragInputIter;
982
983        fn elements(&self) -> FragInputIter {
984            FragInputIter(0)
985        }
986    }
987    #[derive(Debug, Copy, Clone)]
988    pub struct FragInputIter(u16);
989
990    impl Iterator for FragInputIter {
991        type Item = ShaderInterfaceDefEntry;
992
993        #[inline]
994        fn next(&mut self) -> Option<Self::Item> {
995            None
996        }
997
998        #[inline]
999        fn size_hint(&self) -> (usize, Option<usize>) {
1000            (0, Some(0))
1001        }
1002    }
1003
1004    impl ExactSizeIterator for FragInputIter {}
1005
1006    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1007    pub struct FragOutput;
1008    unsafe impl ShaderInterfaceDef for FragOutput {
1009        type Iter = FragOutputIter;
1010
1011        fn elements(&self) -> FragOutputIter {
1012            FragOutputIter(0)
1013        }
1014    }
1015
1016    #[derive(Debug, Copy, Clone)]
1017    pub struct FragOutputIter(u16);
1018
1019    impl Iterator for FragOutputIter {
1020        type Item = ShaderInterfaceDefEntry;
1021
1022        #[inline]
1023        fn next(&mut self) -> Option<Self::Item> {
1024            if self.0 == 0 {
1025                self.0 += 1;
1026                return Some(ShaderInterfaceDefEntry {
1027                    location: 0..1,
1028                    format: Format::R32G32B32A32Sfloat,
1029                    name: Some(Cow::Borrowed("f_color")),
1030                });
1031            }
1032            None
1033        }
1034        #[inline]
1035        fn size_hint(&self) -> (usize, Option<usize>) {
1036            let len = (1 - self.0) as usize;
1037            (len, Some(len))
1038        }
1039    }
1040
1041    impl ExactSizeIterator for FragOutputIter {}
1042
1043    // Layout same as with vertex shader.
1044    #[derive(Debug, Copy, Clone)]
1045    pub struct FragLayout(ShaderStages);
1046    unsafe impl PipelineLayoutDesc for FragLayout {
1047        fn num_sets(&self) -> usize {
1048            1
1049        }
1050        fn num_bindings_in_set(&self, _set: usize) -> Option<usize> {
1051            Some(3)
1052        }
1053        fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
1054            if set == 0 && binding == 0 {
1055                return Some(DescriptorDesc {
1056                    ty: DescriptorDescTy::InputAttachment{
1057                        multisampled: false,
1058                        array_layers: DescriptorImageDescArray::NonArrayed,
1059                    },
1060                    array_count: 1,
1061                    stages: ShaderStages{
1062                        fragment: true,
1063                        ..ShaderStages::none()
1064                    },
1065                    readonly: true
1066                });
1067            } else if set == 0 && binding <= 2 {
1068                return Some(DescriptorDesc {
1069                    ty: DescriptorDescTy::InputAttachment{
1070                        multisampled: false,
1071                        array_layers: DescriptorImageDescArray::NonArrayed,
1072                    },
1073                    array_count: 1,
1074                    stages: ShaderStages{
1075                        fragment: true,
1076                        ..ShaderStages::none()
1077                    },
1078                    readonly: true
1079                });
1080            } else {
1081                return None;
1082            }
1083        }
1084        fn num_push_constants_ranges(&self) -> usize {
1085            1
1086        }
1087        fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> {
1088            Some(
1089                PipelineLayoutDescPcRange{
1090                    offset: 0,
1091                    size: 16,
1092                    stages: ShaderStages{
1093                        fragment: true,
1094                        ..ShaderStages::none()
1095                    },
1096                }
1097            )
1098        }
1099    }
1100
1101    pub struct Shader {
1102        module: Arc<ShaderModule>
1103    }
1104    impl Shader {
1105        pub fn load(device: Arc<Device>) -> Result<Self, OomError> {
1106            Ok(Shader{ module: unsafe { ShaderModule::new(device.clone(), &SPIRV) }? })
1107        }
1108        pub fn main_entry_point(&self) -> GraphicsEntryPoint<(), FragInput, FragOutput, FragLayout> {
1109            unsafe{ 
1110                self.module.graphics_entry_point(
1111                    CStr::from_bytes_with_nul_unchecked(b"main\0"),
1112                    FragInput,
1113                    FragOutput,
1114                    FragLayout(ShaderStages {
1115                        fragment: true,
1116                        ..ShaderStages::none()
1117                    }),
1118                    GraphicsShaderType::Fragment,
1119                )
1120            }
1121        }
1122    }
1123
1124    // vulkano_shaders::shader! {
1125    //     ty: "fragment",
1126    //     path: "./src/shaders/lighting/fs_lighting_ambient.frag"
1127    // }
1128}