|  |  |  | @ -2,7 +2,7 @@ use std::{collections::HashMap, iter}; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | use ash::{ | 
			
		
	
		
			
				
					|  |  |  |  |     khr::{surface, swapchain}, | 
			
		
	
		
			
				
					|  |  |  |  |     vk::{self, DescriptorSet}, | 
			
		
	
		
			
				
					|  |  |  |  |     vk::{self}, | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | use crate::{ | 
			
		
	
	
		
			
				
					|  |  |  | @ -19,11 +19,22 @@ use super::{ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /// Anything can be rendered in world
 | 
			
		
	
		
			
				
					|  |  |  |  | pub trait WorldComponent { | 
			
		
	
		
			
				
					|  |  |  |  |     /// Return the types and number of descriptors this component wants to use
 | 
			
		
	
		
			
				
					|  |  |  |  |     fn descriptors(&self) -> HashMap<vk::DescriptorType, u32>; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// Return the layout of the descriptor set this component wants to used,
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// the used descriptors should match [`WorldComponent::descriptors`]
 | 
			
		
	
		
			
				
					|  |  |  |  |     fn desc_layout(&self, ctx: &RenderCtx) -> vk::DescriptorSetLayout; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// Skybox is passed in for reflections
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// Write to this components descriptor set, the passed descriptor set
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// is layed out like was requested in [`WorldComponent::desc_layout`]
 | 
			
		
	
		
			
				
					|  |  |  |  |     ///
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// Skybox is currently passed in for reflections
 | 
			
		
	
		
			
				
					|  |  |  |  |     ///
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// Note:
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// This api might be changed to having this functions return the
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// [`vk::WriteDescriptorSet`]s it wants, so that the render context
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// does not have to be passed in
 | 
			
		
	
		
			
				
					|  |  |  |  |     fn write_desc_set( | 
			
		
	
		
			
				
					|  |  |  |  |         &self, | 
			
		
	
		
			
				
					|  |  |  |  |         ctx: &RenderCtx, | 
			
		
	
	
		
			
				
					|  |  |  | @ -31,8 +42,16 @@ pub trait WorldComponent { | 
			
		
	
		
			
				
					|  |  |  |  |         skybox: (vk::ImageView, vk::Sampler), | 
			
		
	
		
			
				
					|  |  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// Return the pipeline and pipeline layout this component wants to use,
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// this function is called every frame, so the component should not
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// contruct the pipeline in this function, but merely return an earlier
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// contructed pipeline
 | 
			
		
	
		
			
				
					|  |  |  |  |     fn pipeline(&self) -> (vk::Pipeline, vk::PipelineLayout); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// Return the constants that must be pushed to the shader,
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// camera, screen resolution and base color are provided
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// as they are relevant for most shaders.
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// Return in `(stage, offset, data)`
 | 
			
		
	
		
			
				
					|  |  |  |  |     fn push_constants( | 
			
		
	
		
			
				
					|  |  |  |  |         &self, | 
			
		
	
		
			
				
					|  |  |  |  |         camera: &Camera, | 
			
		
	
	
		
			
				
					|  |  |  | @ -41,12 +60,19 @@ pub trait WorldComponent { | 
			
		
	
		
			
				
					|  |  |  |  |     ) -> Vec<(vk::ShaderStageFlags, u32, Vec<u8>)>; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /// A [`WorldComponent`] and its associated [`vk::DescriptorSet`]
 | 
			
		
	
		
			
				
					|  |  |  |  | pub struct Component { | 
			
		
	
		
			
				
					|  |  |  |  |     pub inner: Box<dyn WorldComponent>, | 
			
		
	
		
			
				
					|  |  |  |  |     pub desc_set: DescriptorSet, | 
			
		
	
		
			
				
					|  |  |  |  |     pub desc_set: vk::DescriptorSet, | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | impl Game<RenderAvailable> { | 
			
		
	
		
			
				
					|  |  |  |  |     /// Start the loading of a world
 | 
			
		
	
		
			
				
					|  |  |  |  |     ///
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// FIXME: This should not remain in [`crate::render`],
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// the function here should be replaced with one for render
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// specifically and this should be moved to [`crate::game`]
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// and call the render specific function from there
 | 
			
		
	
		
			
				
					|  |  |  |  |     pub fn start_load_world(self) -> Game<LoadingWorld> { | 
			
		
	
		
			
				
					|  |  |  |  |         let Self { | 
			
		
	
		
			
				
					|  |  |  |  |             state: | 
			
		
	
	
		
			
				
					|  |  |  | @ -118,6 +144,8 @@ impl Game<RenderAvailable> { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | impl Game<LoadingWorld> { | 
			
		
	
		
			
				
					|  |  |  |  |     /// Add a component to be rendered to the world, see [`crate::render::cube`]
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// for an example for such a component
 | 
			
		
	
		
			
				
					|  |  |  |  |     pub fn add_component<C: WorldComponent + 'static>(&mut self, component: C) { | 
			
		
	
		
			
				
					|  |  |  |  |         let Self { | 
			
		
	
		
			
				
					|  |  |  |  |             state: | 
			
		
	
	
		
			
				
					|  |  |  | @ -136,6 +164,12 @@ impl Game<LoadingWorld> { | 
			
		
	
		
			
				
					|  |  |  |  |         components.push(Box::new(component)); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// Finish loading of a world, it is now ready for play
 | 
			
		
	
		
			
				
					|  |  |  |  |     ///
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// FIXME: This should not remain in [`crate::render`],
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// the function here should be replaced with one for render
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// specifically and this should be moved to [`crate::game`]
 | 
			
		
	
		
			
				
					|  |  |  |  |     /// and call the render specific function from there
 | 
			
		
	
		
			
				
					|  |  |  |  |     pub fn start_world(self) -> Game<InWorld> { | 
			
		
	
		
			
				
					|  |  |  |  |         println!("Starting world"); | 
			
		
	
		
			
				
					|  |  |  |  |         let Self { | 
			
		
	
	
		
			
				
					|  |  |  | 
 |