1 begin@ renderer 2 3 type Pass = 4 val guard : Object -> bool 5 val objects = List<Object>.new 6 val object_ubos = List<ObjectUbo>.new 7 var object_buffer : StorageBuffer = null 8 var object_buffer_size : u32 = 0 9 var skin_buffer : StorageBuffer = null 10 var descriptor_set : DescriptorSet = null 11 12 object Renderer 13 val copy_object_to_ubo = CompositeAction<(Object, mut ref ObjectUbo)>.new 14 15 type Renderer @[mut local] = 16 val vulkan : Vulkan @auto 17 val size : mut Atom<Size> @mut 18 val cameras @[mut private] = List<Camera>.new 19 val camera : Camera 20 val passes : List<Pass> 21 var scene_ubo : SceneUbo 22 val scene_buffer : UniformBuffer 23 val skin_matrices = List<Matrix4>.new 24 var skin_buffer : StorageBuffer 25 var skin_buffer_size : u32 26 val skinned = List<Drawable>.new 27 val lighting : Lighting 28 val field : Field 29 val nodes : List<Node> 30 val cull_mode : CullModeFlags 31 val maybe_blit_image : Option<BlitImage> 32 let tokens = List<Token>.new 33 34 def push_token (token : Token) = 35 tokens.add token 36 37 def add self (camera : Camera) (object : Object) = 38 let index = 39 let maybe_index = self.cameras.try_index_of camera 40 case maybe_index of 41 Some index -> index 42 None -> 43 self.cameras.add camera 44 self.cameras.size - 1 45 46 object.camera_index = index 47 for pass in self.passes do 48 if pass.guard object then 49 pass.objects.add object 50 51 def clear = 52 for pass in passes do 53 pass.objects.clear 54 55 cameras.clear 56 skin_matrices.clear 57 skinned.clear 58 59 local update_pass (pass_index : u32) = 60 let pass = passes[pass_index] 61 pass.object_ubos.clear 62 for object in pass.objects do 63 let mut ubo = ObjectUbo 64 world = object.transform.transpose 65 color = object.color 66 emission = object.emission 67 camera_index = object.camera_index 68 aabb = object.aabb 69 skin_offset = object.skin_offset 70 71 Renderer.copy_object_to_ubo.invoke (object, ubo@mut_ref) 72 pass.object_ubos.add ubo 73 74 let mut update_descriptor_set = false 75 let mut discard_descriptor_set = false 76 if pass.object_buffer == null 77 || pass.object_buffer_size < pass.object_ubos.size * sizeof ObjectUbo 78 then 79 if pass.object_buffer <> null then 80 vulkan.unused_buffers.add pass.object_buffer 81 discard_descriptor_set = true 82 83 let buffer_size = pass.object_ubos.size * sizeof ObjectUbo 84 |> max Renderer.object_buffer_min_size 85 |> ceil_to_power_of_2 86 87 pass.object_buffer = StorageBuffer.create buffer_size 88 pass.object_buffer_size = buffer_size 89 update_descriptor_set = true 90 91 if pass.skin_buffer <> self.skin_buffer then 92 if pass.skin_buffer <> null then 93 discard_descriptor_set = true 94 95 update_descriptor_set = true 96 pass.skin_buffer = self.skin_buffer 97 98 if discard_descriptor_set then 99 pass.descriptor_set.discard 100 101 if update_descriptor_set then 102 pass.descriptor_set = DescriptorSet.create 103 [self.scene_buffer.to_descriptor "scene" 104 pass.object_buffer.to_descriptor "objects" 105 pass.skin_buffer.to_descriptor "skins"] 106 lighting.pipeline_layout[Renderer.scene_set] 107 108 if pass.object_ubos.size > 0 then 109 pass.object_buffer.update pass.object_ubos.as_slice BarrierFlags/Raster 110