diff --git a/src/core/app/mod.rs b/src/core/app/mod.rs index c62e4d5..d951acb 100644 --- a/src/core/app/mod.rs +++ b/src/core/app/mod.rs @@ -113,10 +113,7 @@ impl ApplicationHandler for App { // Now use the created context to load the scene let mut scene_manager = SceneManager::new(); - { - let context = app_context.borrow(); - scene_manager.load_scene(Box::new(MainScene::default()), &context); - } + scene_manager.set_new_scene(Box::new(MainScene::default())); self.scene_manager.insert(window_id, scene_manager); } @@ -240,10 +237,7 @@ impl ApplicationHandler for App { } UserEvent::ChangeScene(window_id, scene) => { if let Some(scene_manager) = self.scene_manager.get_mut(&window_id) { - if let Some(app_context) = self.app_contexts.get(&window_id) { - let context = app_context.borrow(); - scene_manager.replace_current_scene(scene, &context); - } + scene_manager.set_new_scene(scene); } } UserEvent::ChangeResolution(window_id, width, height) => { diff --git a/src/core/render/resources/pipeline/loader.rs b/src/core/render/resources/pipeline/loader.rs index e5e0aeb..92c5f9a 100644 --- a/src/core/render/resources/pipeline/loader.rs +++ b/src/core/render/resources/pipeline/loader.rs @@ -5,6 +5,7 @@ use std::{ sync::{Arc, RwLock}, }; +use bevy_ecs::resource::Resource; use vulkano::{device::Device, format::Format, pipeline::GraphicsPipeline}; use super::{GraphicsPipelineLoadFn, LoadableGraphicsPipeline}; @@ -15,6 +16,7 @@ pub enum PipelineState { Loaded, } +#[derive(Resource)] pub struct PipelineLoader { device: Arc, swapchain_image_format: Format, diff --git a/src/core/render/resources/texture/loader.rs b/src/core/render/resources/texture/loader.rs index b408003..2f34d4b 100644 --- a/src/core/render/resources/texture/loader.rs +++ b/src/core/render/resources/texture/loader.rs @@ -11,11 +11,7 @@ use vulkano::{ memory::allocator::StandardMemoryAllocator, }; -use crate::core::render::primitives::vulkan_resource::{ - VulkanCommandBufferAllocator, VulkanDevice, VulkanGraphicsQueue, VulkanMemoryAllocator, - VulkanTransferQueue, -}; -use bevy_ecs::{resource::Resource, world::World}; +use bevy_ecs::resource::Resource; use super::Texture; diff --git a/src/core/scene/manager.rs b/src/core/scene/manager.rs index e787dcb..5f63f4e 100644 --- a/src/core/scene/manager.rs +++ b/src/core/scene/manager.rs @@ -1,33 +1,42 @@ -use std::cell::RefCell; use std::error::Error; -use std::rc::Rc; +use crate::core::app::DEPTH_IMAGE_ID; use crate::core::app::context::WindowContext; use crate::core::render::primitives::vulkan_resource::{ VulkanCommandBufferAllocator, VulkanComputeQueue, VulkanDescriptorSetAllocator, VulkanDevice, VulkanGraphicsQueue, VulkanInstance, VulkanMemoryAllocator, VulkanTransferQueue, }; +use crate::core::render::resources::pipeline::PipelineLoader; use crate::core::render::resources::texture::TextureLoader; +use crate::core::scene::AsScene; use bevy_ecs::world::World; -use super::{AsScene, Scene}; +use super::Scene; +#[derive(Default)] pub struct SceneManager { - scenes: Vec, - current_scene_index: Option, + current_scene: Option, + new_scene: Option>, } impl SceneManager { pub fn new() -> Self { Self { - scenes: Vec::new(), - current_scene_index: None, + current_scene: None, + new_scene: None, } } - fn create_world_with_resources(window_context: &WindowContext) -> World { + fn create_world_with_resources(window_context: &mut WindowContext) -> World { let mut world = World::new(); + let depth_image_view = window_context.with_renderer_mut(|renderer| { + renderer.get_additional_image_view(DEPTH_IMAGE_ID).clone() + }); + + let swapchain_image_view = + window_context.with_renderer(|renderer| renderer.swapchain_image_view().clone()); + let vulkan_context = window_context.vulkan_context(); let vulkano_context = vulkan_context.vulkano_context(); @@ -47,6 +56,12 @@ impl SceneManager { TextureLoader::select_best_suitable_queue(vulkan_graphics_queue, vulkan_transfer_queue), ); + let pipeline_loader = PipelineLoader::new( + vulkan_device.clone(), + swapchain_image_view.format(), + depth_image_view.format(), + ); + world.insert_resource(VulkanInstance(vulkan_instance.clone())); world.insert_resource(VulkanDevice(vulkan_device.clone())); world.insert_resource(VulkanGraphicsQueue(vulkan_graphics_queue.clone())); @@ -60,59 +75,37 @@ impl SceneManager { vulkan_descriptor_set_allocator.clone(), )); world.insert_resource(texture_loader); + world.insert_resource(pipeline_loader); world } - pub fn load_scene(&mut self, scene_impl: Box, window_context: &WindowContext) { - let world = Self::create_world_with_resources(window_context); - let scene = Scene::new(scene_impl, world); - self.scenes.push(scene); - self.current_scene_index = Some(self.scenes.len() - 1); - } - - pub fn replace_current_scene( - &mut self, - scene_impl: Box, - window_context: &WindowContext, - ) { - if let Some(index) = self.current_scene_index { - if index < self.scenes.len() { - self.scenes[index].unload(); - let world = Self::create_world_with_resources(window_context); - self.scenes[index] = Scene::new(scene_impl, world); - } - } else { - self.load_scene(scene_impl, window_context); - } + pub fn set_new_scene(&mut self, scene_impl: Box) { + self.new_scene = Some(scene_impl); } pub fn current_scene(&self) -> Option<&Scene> { - if let Some(index) = self.current_scene_index { - self.scenes.get(index) - } else { - None - } + self.current_scene.as_ref() } pub fn current_scene_mut(&mut self) -> Option<&mut Scene> { - if let Some(index) = self.current_scene_index { - self.scenes.get_mut(index) - } else { - None - } + self.current_scene.as_mut() } pub fn load_scene_if_not_loaded( &mut self, window_context: &mut WindowContext, ) -> Result<(), Box> { - if let Some(scene) = self.current_scene_mut() { - if !scene.loaded() { - scene.load(window_context)?; + if let Some(new_scene) = self.new_scene.take() { + let world = Self::create_world_with_resources(window_context); + let mut scene = Scene::new(new_scene, world); + scene.load(window_context)?; + + if let Some(mut current_scene) = self.current_scene.take() { + current_scene.unload(); } - } else { - tracing::warn!("No scene found in SceneManager!"); + + self.current_scene = Some(scene); } Ok(()) } diff --git a/src/game/scenes/main_scene.rs b/src/game/scenes/main_scene.rs index 69cb263..6e561bb 100644 --- a/src/game/scenes/main_scene.rs +++ b/src/game/scenes/main_scene.rs @@ -9,7 +9,7 @@ use crate::core::render::primitives::camera::Camera3D; use crate::core::render::primitives::transform::Transform; use crate::core::render::primitives::velocity::Velocity; use crate::core::render::primitives::vulkan_resource::{ - VulkanCommandBufferAllocator, VulkanDescriptorSetAllocator, VulkanDevice, VulkanGraphicsQueue, + VulkanCommandBufferAllocator, VulkanDescriptorSetAllocator, VulkanGraphicsQueue, VulkanMemoryAllocator, }; use crate::core::render::primitives::{AsDescriptorSet, AsRecordable}; @@ -42,7 +42,6 @@ pub struct Square; pub struct Cube; pub struct MainSceneState { - pipeline_loader: PipelineLoader, square: SquareMesh, obj: ObjMesh, camera: Camera3D, @@ -65,18 +64,7 @@ impl AsScene for MainScene { world: &mut World, window_context: &mut WindowContext, ) -> Result<(), Box> { - let depth_image_view = window_context.with_renderer_mut(|renderer| { - renderer.get_additional_image_view(DEPTH_IMAGE_ID).clone() - }); - - let swapchain_image_view = - window_context.with_renderer(|renderer| renderer.swapchain_image_view().clone()); - - let mut pipeline_loader = PipelineLoader::new( - VulkanDevice::get_from_world(world).clone(), - swapchain_image_view.format(), - depth_image_view.format(), - ); + let mut pipeline_loader = world.resource_mut::(); pipeline_loader.register::()?; pipeline_loader.load_pending_pipelines()?; @@ -138,7 +126,6 @@ impl AsScene for MainScene { self.state = Some(MainSceneState { square, obj, - pipeline_loader, camera, speed: 50.0, scheduler, @@ -257,36 +244,35 @@ impl AsScene for MainScene { )?; let texture_loader = world.resource::(); + let pipeline_loader = world.resource::(); - state - .pipeline_loader - .with_pipeline::(|pipeline| { - SimplePipeline::record_commands( - &mut builder, - &VulkanDescriptorSetAllocator::get_from_world(world), - pipeline, - &state.square, - &square_transform_uniform, - vec![ - camera_uniform.clone() as Arc, - texture_loader.get_texture("wooden-crate").unwrap().clone(), - ], - )?; + pipeline_loader.with_pipeline::(|pipeline| { + SimplePipeline::record_commands( + &mut builder, + &VulkanDescriptorSetAllocator::get_from_world(world), + pipeline, + &state.square, + &square_transform_uniform, + vec![ + camera_uniform.clone() as Arc, + texture_loader.get_texture("wooden-crate").unwrap().clone(), + ], + )?; - SimplePipeline::record_commands( - &mut builder, - &VulkanDescriptorSetAllocator::get_from_world(world), - pipeline, - &state.obj, - &cube_transform_uniform, - vec![ - camera_uniform.clone() as Arc, - texture_loader.get_texture("cube-diffuse").unwrap().clone(), - ], - )?; + SimplePipeline::record_commands( + &mut builder, + &VulkanDescriptorSetAllocator::get_from_world(world), + pipeline, + &state.obj, + &cube_transform_uniform, + vec![ + camera_uniform.clone() as Arc, + texture_loader.get_texture("cube-diffuse").unwrap().clone(), + ], + )?; - Ok(()) - })?; + Ok(()) + })?; RenderPassManager::end_rendering(&mut builder)?;