|  |  |  | @ -267,14 +267,14 @@ typedef struct PositionStruct { | 
		
	
		
			
				|  |  |  |  | typedef struct AttributeMappingStruct { | 
		
	
		
			
				|  |  |  |  |   uint32_t attribute_id; // Which attribute to map
 | 
		
	
		
			
				|  |  |  |  |   uint32_t mapping_type; // What function to use to map it
 | 
		
	
		
			
				|  |  |  |  |   uint32_t binding; // Which index to use in the ATTRIBUTE_ID_DESTRO
 | 
		
	
		
			
				|  |  |  |  |   uint32_t binding; // Which index to use in the ATTRIBUTE_ID_DESCRIPTORS array
 | 
		
	
		
			
				|  |  |  |  | } AttributeMapping; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #define ATTRIBUTE_ID_MESH            0x00000001 | 
		
	
		
			
				|  |  |  |  | #define ATTRIBUTE_ID_MATERIAL        0x00000002 | 
		
	
		
			
				|  |  |  |  | #define ATTRIBUTE_ID_DESCRIPTORS     0x00000003 | 
		
	
		
			
				|  |  |  |  | #define ATTRIBUTE_ID_DESCRIPTOR_SETS 0x00000004 | 
		
	
		
			
				|  |  |  |  | #define ATTRIBUTE_ID_POSITION        0x00000005 | 
		
	
		
			
				|  |  |  |  | #define ATTRIBUTE_ID_MESH            0x00000001 // Mesh*
 | 
		
	
		
			
				|  |  |  |  | #define ATTRIBUTE_ID_MATERIAL        0x00000002 // Material*
 | 
		
	
		
			
				|  |  |  |  | #define ATTRIBUTE_ID_DESCRIPTORS     0x00000003 // void***(array of array of data pointers)
 | 
		
	
		
			
				|  |  |  |  | #define ATTRIBUTE_ID_DESCRIPTOR_SETS 0x00000004 // VkDescriptorSet*
 | 
		
	
		
			
				|  |  |  |  | #define ATTRIBUTE_ID_POSITION        0x00000005 // Position*
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | typedef struct ObjectStruct { | 
		
	
		
			
				|  |  |  |  |   Map      attributes; | 
		
	
	
		
			
				
					|  |  |  | @ -291,8 +291,8 @@ typedef struct MeshTypeStruct { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Defines what descriptors are bound at two different upate rates for the pipeline
 | 
		
	
		
			
				|  |  |  |  | typedef struct PipelineLayoutStruct { | 
		
	
		
			
				|  |  |  |  |   uint32_t                      mesh_bindings_count; | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayoutBinding* mesh_bindings; | 
		
	
		
			
				|  |  |  |  |   uint32_t                      object_bindings_count; | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayoutBinding* object_bindings; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   uint32_t                      material_bindings_count; | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayoutBinding* material_bindings; | 
		
	
	
		
			
				
					|  |  |  | @ -308,7 +308,7 @@ typedef struct MeshStruct { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | typedef struct MaterialStruct { | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayout material_set_layout; | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayout mesh_set_layout; | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayout object_set_layout; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineLayout layout; | 
		
	
		
			
				|  |  |  |  |   VkPipeline       pipeline; | 
		
	
	
		
			
				
					|  |  |  | @ -316,6 +316,8 @@ typedef struct MaterialStruct { | 
		
	
		
			
				|  |  |  |  |   VkDescriptorPool material_descriptor_pool; | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSet* material_descriptors; | 
		
	
		
			
				|  |  |  |  |   uint32_t         material_descriptors_count; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   Map              object_descriptor_mappings; | 
		
	
		
			
				|  |  |  |  | } Material; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | typedef struct VulkanContextStruct { | 
		
	
	
		
			
				
					|  |  |  | @ -1815,7 +1817,7 @@ void command_draw_object(Material material, Object object, uint32_t frame_num, V | 
		
	
		
			
				|  |  |  |  |   vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offsets); | 
		
	
		
			
				|  |  |  |  |   vkCmdBindIndexBuffer(command_buffer, mesh->index_buffer.buffer, 0, VK_INDEX_TYPE_UINT16); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   if(material.mesh_set_layout != VK_NULL_HANDLE) { | 
		
	
		
			
				|  |  |  |  |   if(material.object_set_layout != VK_NULL_HANDLE) { | 
		
	
		
			
				|  |  |  |  |     MaybeValue maybe_descriptors = map_lookup(object.attributes, ATTRIBUTE_ID_DESCRIPTOR_SETS); | 
		
	
		
			
				|  |  |  |  |     if(maybe_descriptors.has_value == false) { | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
	
		
			
				
					|  |  |  | @ -1828,18 +1830,18 @@ void command_draw_object(Material material, Object object, uint32_t frame_num, V | 
		
	
		
			
				|  |  |  |  |   vkCmdDrawIndexed(command_buffer, mesh->index_count, 1, 0, 0, 0); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void command_draw_material(Material material, uint32_t mesh_count, Object* objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, VkCommandBuffer command_buffer) { | 
		
	
		
			
				|  |  |  |  | void command_draw_material(Material material, uint32_t object_count, Object* objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, VkCommandBuffer command_buffer) { | 
		
	
		
			
				|  |  |  |  |   vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline); | 
		
	
		
			
				|  |  |  |  |   vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 0, 1, &scene_descriptors[frame_num], 0, 0); | 
		
	
		
			
				|  |  |  |  |   if(material.material_descriptors != 0) { | 
		
	
		
			
				|  |  |  |  |     vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 1, 1, &material.material_descriptors[frame_num], 0, 0); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   for(uint32_t i = 0; i < mesh_count; i++) { | 
		
	
		
			
				|  |  |  |  |   for(uint32_t i = 0; i < object_count; i++) { | 
		
	
		
			
				|  |  |  |  |     command_draw_object(material, objects[i], frame_num, command_buffer); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint32_t* mesh_counts, Object** objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) { | 
		
	
		
			
				|  |  |  |  | VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint32_t* object_counts, Object** objects, uint32_t frame_num, VkDescriptorSet* scene_descriptors, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) { | 
		
	
		
			
				|  |  |  |  |   VkCommandBufferBeginInfo begin_info = {}; | 
		
	
		
			
				|  |  |  |  |   begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; | 
		
	
		
			
				|  |  |  |  |   begin_info.flags = 0; | 
		
	
	
		
			
				
					|  |  |  | @ -1888,7 +1890,7 @@ VkResult command_draw_scene(uint32_t materials_count, Material* materials, uint3 | 
		
	
		
			
				|  |  |  |  |   vkCmdSetScissor(command_buffer, 0, 1, &scissor); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   for(uint i = 0; i < materials_count; i++) { | 
		
	
		
			
				|  |  |  |  |     command_draw_material(materials[i], mesh_counts[i], objects[i], frame_num, scene_descriptors, command_buffer); | 
		
	
		
			
				|  |  |  |  |     command_draw_material(materials[i], object_counts[i], objects[i], frame_num, scene_descriptors, command_buffer); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   vkCmdEndRenderPass(command_buffer); | 
		
	
	
		
			
				
					|  |  |  | @ -2088,7 +2090,7 @@ Material create_material( | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayout material_set_layout; | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayout mesh_set_layout; | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayout object_set_layout; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkDescriptorPool material_descriptor_pool = VK_NULL_HANDLE; | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSet* material_descriptors = 0; | 
		
	
	
		
			
				
					|  |  |  | @ -2163,15 +2165,15 @@ Material create_material( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayoutCreateInfo mesh_layout_info = { | 
		
	
		
			
				|  |  |  |  |     .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, | 
		
	
		
			
				|  |  |  |  |     .bindingCount = pipeline_layout.mesh_bindings_count, | 
		
	
		
			
				|  |  |  |  |     .pBindings = pipeline_layout.mesh_bindings, | 
		
	
		
			
				|  |  |  |  |     .bindingCount = pipeline_layout.object_bindings_count, | 
		
	
		
			
				|  |  |  |  |     .pBindings = pipeline_layout.object_bindings, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   result = vkCreateDescriptorSetLayout(device, &mesh_layout_info, 0, &mesh_set_layout); | 
		
	
		
			
				|  |  |  |  |   result = vkCreateDescriptorSetLayout(device, &mesh_layout_info, 0, &object_set_layout); | 
		
	
		
			
				|  |  |  |  |   if(result != VK_SUCCESS) { | 
		
	
		
			
				|  |  |  |  |     return zero_material; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayout all_layouts[3] = {scene_ubo_layout, material_set_layout, mesh_set_layout}; | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetLayout all_layouts[3] = {scene_ubo_layout, material_set_layout, object_set_layout}; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkPipelineLayout layout; | 
		
	
		
			
				|  |  |  |  |   VkPipelineLayoutCreateInfo layout_info = { | 
		
	
	
		
			
				
					|  |  |  | @ -2197,7 +2199,7 @@ Material create_material( | 
		
	
		
			
				|  |  |  |  |     .pipeline = pipeline, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     .material_set_layout = material_set_layout, | 
		
	
		
			
				|  |  |  |  |     .mesh_set_layout = mesh_set_layout, | 
		
	
		
			
				|  |  |  |  |     .object_set_layout = object_set_layout, | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     .material_descriptors = material_descriptors, | 
		
	
		
			
				|  |  |  |  |     .material_descriptor_pool = material_descriptor_pool, | 
		
	
	
		
			
				
					|  |  |  | @ -2327,8 +2329,8 @@ Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRend | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   PipelineLayout texture_layout = { | 
		
	
		
			
				|  |  |  |  |     .mesh_bindings_count = sizeof(mesh_set_bindings)/sizeof(VkDescriptorSetLayoutBinding), | 
		
	
		
			
				|  |  |  |  |     .mesh_bindings = mesh_set_bindings, | 
		
	
		
			
				|  |  |  |  |     .object_bindings_count = sizeof(mesh_set_bindings)/sizeof(VkDescriptorSetLayoutBinding), | 
		
	
		
			
				|  |  |  |  |     .object_bindings = mesh_set_bindings, | 
		
	
		
			
				|  |  |  |  |   }; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, texture_layout, textured_mesh_type, max_frames_in_flight); | 
		
	
	
		
			
				
					|  |  |  | @ -2699,7 +2701,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   for(uint32_t i = 0; i < max_frames_in_flight; i++) { | 
		
	
		
			
				|  |  |  |  |     TODO_layouts[i] = texture_mesh_material.mesh_set_layout; | 
		
	
		
			
				|  |  |  |  |     TODO_layouts[i] = texture_mesh_material.object_set_layout; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   VkDescriptorSetAllocateInfo TODO_alloc = { | 
		
	
	
		
			
				
					|  |  |  | 
 |