1    type GridUbo = struct
2        dim_j : u32
3        dim_k : u32
4        pad1 : [u32; 2]
5        offset : Vector3
6        pad2 : [u32; 1]
7    
8    type LightingUbo = struct
9        lights : [LightUbo; 4] = memory@zero
10       local_lights : [LocalLightUbo; Renderer.max_local_lights] = memory@zero
11       local_count : u32 = 0
12       pad : [u32; 3] = memory@zero
13       grid : GridUbo = struct@zero
14   
15   type Lighting =
16       val vulkan : Vulkan @auto
17       val lights = List<Light>.new
18       val local_lights @mut = List<LocalLight>.new
19       val buffer : UniformBuffer
20       var ubo : LightingUbo
21       var descriptor_set = DescriptorSet@null
22       val pipeline_layout : PipelineLayout
23       let descriptors = List<(String, OneMany<Resource>)>.new
24   
25       def add (descriptor : (String, OneMany<Resource>)) =
26           descriptors.add descriptor
27   
28   type CompositeAction<T> =
29       let functions = List<T -> Unit>.new
30   
31       def add f =
32           functions.add f
33   
34       def invoke (x : T) =
35           for f in functions do
36               f x
37   
38   object Lighting =
39       def create (pipeline_layout : PipelineLayout) =
40           let size = sizeof LightingUbo
41           let buffer = UniformBuffer.create size.as<u32>
42   
43           Lighting
44               =buffer
45               ubo = LightingUbo.new
46               =pipeline_layout
47   
48       val collect_descriptors = CompositeAction<Lighting>.new
49   
50   type Lighting
51       def update_descriptor_set =
52           if descriptor_set <> null then
53               descriptor_set.discard
54   
55           descriptors.clear
56           buffer.to_descriptor "lighting" |> descriptors.add
57   
58           Lighting.collect_descriptors.invoke self
59   
60           descriptor_set = DescriptorSet.create descriptors.as_slice
61                                                 pipeline_layout[Renderer.lighting_set]
62   
63       def update_buffer =
64           for i = 0 until local_lights.size do
65               let light = local_lights[i]
66               let light_ubo = ubo.local_lights[mut_ref i]
67               light_ubo.direction = [light.direction.x
68                                      light.direction.y
69                                      light.direction.z]
70   
71                         intensity = light.intensity
72                         color = [light.color.x, light.color.y, light.color.z]
73   
74           for i = 0 until lights.size do
75               let light = lights[i]
76               let light_ubo = ubo.lights[mut_ref i]
77               light_ubo.intensity = light.intensity
78                         color = [light.color.x, light.color.y, light.color.z]
79   
80           ubo.local_count = local_lights.size
81   
82           buffer.update_single ubo@ptr BarrierFlags/Raster
83