Integration of ECS pattern: Iteration 1

This commit is contained in:
Florian RICHER 2025-06-11 16:05:35 +02:00
parent fc81f65a27
commit 8ce620a74b
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
13 changed files with 727 additions and 135 deletions

View file

@ -5,13 +5,6 @@ use std::{
};
use egui_winit_vulkano::Gui;
use vulkano::{
command_buffer::allocator::StandardCommandBufferAllocator,
descriptor_set::allocator::StandardDescriptorSetAllocator,
device::{Device, Queue},
instance::Instance,
memory::allocator::StandardMemoryAllocator,
};
use vulkano_util::{renderer::VulkanoWindowRenderer, window::VulkanoWindows};
use winit::{event_loop::EventLoopProxy, monitor::MonitorHandle, window::WindowId};
@ -19,19 +12,10 @@ use crate::core::{input::InputManager, render::vulkan_context::VulkanContext, ti
use super::user_event::UserEvent;
/// Contexte d'application unifié avec Arc<Mutex<>> pour la mutabilité partagée
#[derive(Clone)]
/// Contexte d'application unifié pour les fonctions liées à la fenêtre
pub struct WindowContext {
// Données Vulkan (immutables)
pub vulkan_context: Arc<VulkanContext>,
pub device: Arc<Device>,
pub instance: Arc<Instance>,
pub graphics_queue: Arc<Queue>,
pub compute_queue: Arc<Queue>,
pub transfer_queue: Option<Arc<Queue>>,
pub memory_allocator: Arc<StandardMemoryAllocator>,
pub command_buffer_allocator: Arc<StandardCommandBufferAllocator>,
pub descriptor_set_allocator: Arc<StandardDescriptorSetAllocator>,
pub event_loop_proxy: EventLoopProxy<UserEvent>,
pub window_id: WindowId,
@ -52,19 +36,9 @@ impl WindowContext {
event_loop_proxy: EventLoopProxy<UserEvent>,
window_id: WindowId,
) -> Self {
let vulkano_context_inner = vulkan_context.vulkano_context();
Self {
// Données Vulkan
vulkan_context: vulkan_context.clone(),
device: vulkano_context_inner.device().clone(),
instance: vulkano_context_inner.instance().clone(),
graphics_queue: vulkano_context_inner.graphics_queue().clone(),
compute_queue: vulkano_context_inner.compute_queue().clone(),
transfer_queue: vulkano_context_inner.transfer_queue().cloned(),
memory_allocator: vulkano_context_inner.memory_allocator().clone(),
command_buffer_allocator: vulkan_context.command_buffer_allocator().clone(),
descriptor_set_allocator: vulkan_context.descriptor_set_allocator().clone(),
vulkan_context,
event_loop_proxy,
window_id,
@ -76,6 +50,10 @@ impl WindowContext {
}
}
pub fn vulkan_context(&self) -> &VulkanContext {
&self.vulkan_context
}
/// Extrait les résolutions d'un moniteur donné
fn extract_resolutions_from_monitor(monitor: MonitorHandle) -> Vec<(u32, u32)> {
let video_modes: Vec<_> = monitor.video_modes().collect();

View file

@ -99,11 +99,7 @@ impl ApplicationHandler<UserEvent> for App {
};
self.gui.insert(window_id, Rc::new(RefCell::new(gui)));
let mut scene_manager = SceneManager::new();
scene_manager.load_scene(Box::new(MainScene::default()));
self.scene_manager.insert(window_id, scene_manager);
// Create the WindowContext with simplified arguments
let app_context = Rc::new(RefCell::new(WindowContext::new(
self.vulkan_context.clone(),
self.vulkano_windows.clone(),
@ -113,7 +109,16 @@ impl ApplicationHandler<UserEvent> for App {
self.event_loop_proxy.clone(),
window_id,
)));
self.app_contexts.insert(window_id, app_context);
self.app_contexts.insert(window_id, app_context.clone());
// 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);
}
self.scene_manager.insert(window_id, scene_manager);
}
fn device_event(
@ -181,7 +186,7 @@ impl ApplicationHandler<UserEvent> for App {
if let Some(scene) = scene_manager.current_scene_mut() {
{
let _update_span = tracing::debug_span!("scene_update").entered();
scene.update(&mut context).unwrap();
scene.0.update(&mut scene.1, &context).unwrap();
}
let acquire_future = {
@ -193,7 +198,10 @@ impl ApplicationHandler<UserEvent> for App {
let acquire_future = {
let _render_span = tracing::debug_span!("scene_render").entered();
scene.render(acquire_future, &mut context).unwrap()
scene
.0
.render(acquire_future, &mut scene.1, &mut context)
.unwrap()
};
{
@ -235,7 +243,10 @@ impl ApplicationHandler<UserEvent> for App {
}
UserEvent::ChangeScene(window_id, scene) => {
if let Some(scene_manager) = self.scene_manager.get_mut(&window_id) {
scene_manager.load_scene(scene);
if let Some(app_context) = self.app_contexts.get(&window_id) {
let context = app_context.borrow();
scene_manager.load_scene(scene, &context);
}
}
}
UserEvent::ChangeResolution(window_id, width, height) => {

View file

@ -1,6 +1,7 @@
mod buffer;
mod command;
mod descriptor_set;
pub mod vulkan_resource;
pub mod camera;
pub mod mvp;

View file

@ -4,7 +4,7 @@ use std::sync::Arc;
use vulkano::buffer::{
AllocateBufferError, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer,
};
use vulkano::descriptor_set::allocator::{DescriptorSetAllocator, StandardDescriptorSetAllocator};
use vulkano::descriptor_set::allocator::StandardDescriptorSetAllocator;
use vulkano::descriptor_set::layout::{
DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorType,
};

View file

@ -0,0 +1,79 @@
use bevy_ecs::prelude::Resource;
use bevy_ecs::world::World;
use std::sync::Arc;
use vulkano::{
command_buffer::allocator::StandardCommandBufferAllocator,
descriptor_set::allocator::StandardDescriptorSetAllocator,
device::{Device, Queue},
instance::Instance,
memory::allocator::StandardMemoryAllocator,
};
/// Vulkan Instance resource
#[derive(Resource)]
pub struct VulkanInstance(pub Arc<Instance>);
/// Vulkan Device resource
#[derive(Resource)]
pub struct VulkanDevice(pub Arc<Device>);
/// Vulkan Graphics Queue resource
#[derive(Resource)]
pub struct VulkanGraphicsQueue(pub Arc<Queue>);
/// Vulkan Compute Queue resource
#[derive(Resource)]
pub struct VulkanComputeQueue(pub Arc<Queue>);
/// Vulkan Transfer Queue resource
#[derive(Resource)]
pub struct VulkanTransferQueue(pub Option<Arc<Queue>>);
/// Vulkan Memory Allocator resource
#[derive(Resource)]
pub struct VulkanMemoryAllocator(pub Arc<StandardMemoryAllocator>);
/// Vulkan Command Buffer Allocator resource
#[derive(Resource)]
pub struct VulkanCommandBufferAllocator(pub Arc<StandardCommandBufferAllocator>);
/// Vulkan Descriptor Set Allocator resource
#[derive(Resource)]
pub struct VulkanDescriptorSetAllocator(pub Arc<StandardDescriptorSetAllocator>);
/// Helper functions to access vulkan resources from the ECS world
impl VulkanDevice {
pub fn get_from_world(world: &World) -> &Arc<Device> {
&world.resource::<VulkanDevice>().0
}
}
impl VulkanMemoryAllocator {
pub fn get_from_world(world: &World) -> &Arc<StandardMemoryAllocator> {
&world.resource::<VulkanMemoryAllocator>().0
}
}
impl VulkanCommandBufferAllocator {
pub fn get_from_world(world: &World) -> &Arc<StandardCommandBufferAllocator> {
&world.resource::<VulkanCommandBufferAllocator>().0
}
}
impl VulkanDescriptorSetAllocator {
pub fn get_from_world(world: &World) -> &Arc<StandardDescriptorSetAllocator> {
&world.resource::<VulkanDescriptorSetAllocator>().0
}
}
impl VulkanGraphicsQueue {
pub fn get_from_world(world: &World) -> &Arc<Queue> {
&world.resource::<VulkanGraphicsQueue>().0
}
}
impl VulkanTransferQueue {
pub fn get_from_world(world: &World) -> Option<&Arc<Queue>> {
world.resource::<VulkanTransferQueue>().0.as_ref()
}
}

View file

@ -11,7 +11,11 @@ use vulkano::{
memory::allocator::StandardMemoryAllocator,
};
use crate::core::app::context::WindowContext;
use crate::core::render::primitives::vulkan_resource::{
VulkanCommandBufferAllocator, VulkanDevice, VulkanGraphicsQueue, VulkanMemoryAllocator,
VulkanTransferQueue,
};
use bevy_ecs::world::World;
use super::Texture;
@ -36,21 +40,19 @@ pub struct TextureLoader {
}
impl TextureLoader {
pub fn new(app_context: &WindowContext) -> Self {
pub fn new(world: &World) -> Self {
Self {
loaded_textures: HashMap::new(),
pending_textures: HashMap::new(),
device: app_context.device.clone(),
command_buffer_allocator: app_context.command_buffer_allocator.clone(),
memory_allocator: app_context.memory_allocator.clone(),
queue: Self::select_best_suitable_queue(app_context),
device: VulkanDevice::get_from_world(world).clone(),
command_buffer_allocator: VulkanCommandBufferAllocator::get_from_world(world).clone(),
memory_allocator: VulkanMemoryAllocator::get_from_world(world).clone(),
queue: Self::select_best_suitable_queue(world),
}
}
fn select_best_suitable_queue(app_context: &WindowContext) -> Arc<Queue> {
app_context
.transfer_queue
.as_ref()
fn select_best_suitable_queue(world: &World) -> Arc<Queue> {
VulkanTransferQueue::get_from_world(world)
.map(|queue| {
tracing::trace!(
"Select transfer queue for texture loading with family index: {:?}",
@ -58,14 +60,14 @@ impl TextureLoader {
);
queue.clone()
})
.or_else(|| {
.unwrap_or_else(|| {
let graphics_queue = VulkanGraphicsQueue::get_from_world(world);
tracing::trace!(
"Select graphics queue for texture loading with family index: {:?}",
app_context.graphics_queue.queue_family_index()
graphics_queue.queue_family_index()
);
Some(app_context.graphics_queue.clone())
graphics_queue.clone()
})
.unwrap()
}
pub fn add_texture(&mut self, name: String, load_info: TextureLoadInfo) {

View file

@ -1,12 +1,20 @@
use std::cell::RefCell;
use std::error::Error;
use std::rc::Rc;
use crate::core::app::context::WindowContext;
use crate::core::render::primitives::vulkan_resource::{
VulkanCommandBufferAllocator, VulkanComputeQueue, VulkanDescriptorSetAllocator, VulkanDevice,
VulkanGraphicsQueue, VulkanInstance, VulkanMemoryAllocator, VulkanTransferQueue,
};
use bevy_ecs::world::World;
use super::Scene;
pub struct SceneManager {
scenes: Vec<Box<dyn Scene>>,
scenes: Vec<(Box<dyn Scene>, World)>,
current_scene_index: Option<usize>,
window_context: Option<Rc<RefCell<WindowContext>>>,
}
impl SceneManager {
@ -14,26 +22,95 @@ impl SceneManager {
Self {
scenes: Vec::new(),
current_scene_index: None,
window_context: None,
}
}
pub fn load_scene(&mut self, scene: Box<dyn Scene>) {
self.scenes.push(scene);
pub fn set_window_context(&mut self, window_context: Rc<RefCell<WindowContext>>) {
self.window_context = Some(window_context);
}
fn create_world_with_resources(window_context: &WindowContext) -> World {
let mut world = World::new();
// Add Vulkan resources
world.insert_resource(VulkanInstance(
window_context
.vulkan_context()
.vulkano_context()
.instance()
.clone(),
));
world.insert_resource(VulkanDevice(
window_context
.vulkan_context()
.vulkano_context()
.device()
.clone(),
));
world.insert_resource(VulkanGraphicsQueue(
window_context
.vulkan_context()
.vulkano_context()
.graphics_queue()
.clone(),
));
world.insert_resource(VulkanComputeQueue(
window_context
.vulkan_context()
.vulkano_context()
.compute_queue()
.clone(),
));
world.insert_resource(VulkanTransferQueue(
window_context
.vulkan_context()
.vulkano_context()
.transfer_queue()
.cloned(),
));
world.insert_resource(VulkanMemoryAllocator(
window_context
.vulkan_context()
.vulkano_context()
.memory_allocator()
.clone(),
));
world.insert_resource(VulkanCommandBufferAllocator(
window_context
.vulkan_context()
.command_buffer_allocator()
.clone(),
));
world.insert_resource(VulkanDescriptorSetAllocator(
window_context
.vulkan_context()
.descriptor_set_allocator()
.clone(),
));
world
}
pub fn load_scene(&mut self, scene: Box<dyn Scene>, window_context: &WindowContext) {
let world = Self::create_world_with_resources(window_context);
self.scenes.push((scene, world));
self.current_scene_index = Some(self.scenes.len() - 1);
}
pub fn replace_current_scene(&mut self, scene: Box<dyn Scene>) {
pub fn replace_current_scene(&mut self, scene: Box<dyn Scene>, window_context: &WindowContext) {
if let Some(index) = self.current_scene_index {
if index < self.scenes.len() {
self.scenes[index].unload();
self.scenes[index] = scene;
self.scenes[index].0.unload();
let world = Self::create_world_with_resources(window_context);
self.scenes[index] = (scene, world);
}
} else {
self.load_scene(scene);
self.load_scene(scene, window_context);
}
}
pub fn current_scene(&self) -> Option<&Box<dyn Scene>> {
pub fn current_scene(&self) -> Option<&(Box<dyn Scene>, World)> {
if let Some(index) = self.current_scene_index {
self.scenes.get(index)
} else {
@ -41,7 +118,7 @@ impl SceneManager {
}
}
pub fn current_scene_mut(&mut self) -> Option<&mut Box<dyn Scene>> {
pub fn current_scene_mut(&mut self) -> Option<&mut (Box<dyn Scene>, World)> {
if let Some(index) = self.current_scene_index {
self.scenes.get_mut(index)
} else {
@ -51,11 +128,11 @@ impl SceneManager {
pub fn load_scene_if_not_loaded(
&mut self,
app_context: &mut WindowContext,
window_context: &mut WindowContext,
) -> Result<(), Box<dyn Error>> {
if let Some(scene) = self.current_scene_mut() {
if let Some((scene, world)) = self.current_scene_mut() {
if !scene.loaded() {
scene.load(app_context)?;
scene.load(world, window_context)?;
}
} else {
tracing::warn!("No scene found in SceneManager!");

View file

@ -1,5 +1,6 @@
use std::error::Error;
use bevy_ecs::world::World;
use vulkano::sync::GpuFuture;
use crate::core::app::context::WindowContext;
@ -8,12 +9,21 @@ pub mod manager;
pub trait Scene {
fn loaded(&self) -> bool;
fn load(&mut self, app_context: &mut WindowContext) -> Result<(), Box<dyn Error>>;
fn update(&mut self, app_context: &mut WindowContext) -> Result<(), Box<dyn Error>>;
fn load(
&mut self,
world: &mut World,
window_context: &mut WindowContext,
) -> Result<(), Box<dyn Error>>;
fn update(
&mut self,
world: &mut World,
window_context: &WindowContext,
) -> Result<(), Box<dyn Error>>;
fn render(
&mut self,
acquire_future: Box<dyn GpuFuture>,
app_context: &mut WindowContext,
world: &mut World,
window_context: &mut WindowContext,
) -> Result<Box<dyn GpuFuture>, Box<dyn Error>>;
fn unload(&mut self);
}

View file

@ -1,7 +1,4 @@
use std::{
error::Error,
sync::{Arc, RwLock},
};
use std::{error::Error, sync::Arc};
use vulkano::{
command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer},

View file

@ -1,4 +1,3 @@
use std::collections::HashMap;
use std::error::Error;
use std::sync::Arc;
@ -8,6 +7,10 @@ use crate::core::app::context::WindowContext;
use crate::core::app::user_event::UserEvent;
use crate::core::render::primitives::camera::Camera3D;
use crate::core::render::primitives::transform::Transform;
use crate::core::render::primitives::vulkan_resource::{
VulkanCommandBufferAllocator, VulkanDescriptorSetAllocator, VulkanDevice, VulkanGraphicsQueue,
VulkanMemoryAllocator,
};
use crate::core::render::primitives::{AsDescriptorSet, AsRecordable};
use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager};
use crate::core::render::resources::meshes::{ObjMesh, SquareMesh};
@ -15,6 +18,7 @@ use crate::core::render::resources::pipeline::PipelineLoader;
use crate::core::render::resources::texture::{TextureLoadInfo, TextureLoader, TextureSourceKind};
use crate::core::scene::Scene;
use crate::game::assets::pipelines::simple::SimplePipeline;
use bevy_ecs::world::World;
use egui_winit_vulkano::egui;
use glam::EulerRot;
use glam::Quat;
@ -48,23 +52,27 @@ impl Scene for MainScene {
self.state.is_some()
}
fn load(&mut self, app_context: &mut WindowContext) -> Result<(), Box<dyn std::error::Error>> {
let depth_image_view = app_context.with_renderer_mut(|renderer| {
fn load(
&mut self,
world: &mut World,
window_context: &mut WindowContext,
) -> Result<(), Box<dyn std::error::Error>> {
let depth_image_view = window_context.with_renderer_mut(|renderer| {
renderer.get_additional_image_view(DEPTH_IMAGE_ID).clone()
});
let swapchain_image_view =
app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
window_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
let mut pipeline_loader = PipelineLoader::new(
app_context.device.clone(),
VulkanDevice::get_from_world(world).clone(),
swapchain_image_view.format(),
depth_image_view.format(),
);
pipeline_loader.register::<SimplePipeline>()?;
pipeline_loader.load_pending_pipelines()?;
let mut texture_loader = TextureLoader::new(app_context);
let mut texture_loader = TextureLoader::new(world);
texture_loader.add_texture(
"wooden-crate".to_string(),
TextureLoadInfo {
@ -93,10 +101,13 @@ impl Scene for MainScene {
);
texture_loader.load_pending_textures()?;
let square = SquareMesh::new(&app_context.memory_allocator)?;
let square = SquareMesh::new(VulkanMemoryAllocator::get_from_world(world))?;
let obj = {
let obj = ObjMesh::new(&app_context.memory_allocator, "res/objects/cube.obj")?;
let obj = ObjMesh::new(
VulkanMemoryAllocator::get_from_world(world),
"res/objects/cube.obj",
)?;
obj.into_iter().next().unwrap()
};
@ -139,7 +150,7 @@ impl Scene for MainScene {
})
.collect();
let camera = app_context.with_renderer(|renderer| {
let camera = window_context.with_renderer(|renderer| {
Camera3D::new(
renderer.aspect_ratio(),
std::f32::consts::FRAC_PI_2,
@ -162,21 +173,26 @@ impl Scene for MainScene {
Ok(())
}
fn update(&mut self, app_context: &mut WindowContext) -> Result<(), Box<dyn Error>> {
fn update(
&mut self,
_world: &mut World,
window_context: &WindowContext,
) -> Result<(), Box<dyn Error>> {
let state = self.state.as_mut().unwrap();
app_context.with_input_manager(|input_manager| {
app_context.with_timer(|timer| {
window_context.with_input_manager(|input_manager| {
window_context.with_timer(|timer| {
state.camera.update(
input_manager,
timer,
state.speed,
10.0,
app_context.get_aspect_ratio(),
window_context.get_aspect_ratio(),
);
});
});
let delta_time = app_context.get_delta_time();
let delta_time = window_context.get_delta_time();
for (i, instance) in state.square_instances.iter_mut().enumerate() {
let rotation_speed = (i % 10) as f32;
let rotation_delta = Quat::from_rotation_y(rotation_speed * delta_time);
@ -191,32 +207,32 @@ impl Scene for MainScene {
instance.rotate(rotation_delta);
}
if app_context
if window_context
.with_input_manager(|input_manager| input_manager.get_virtual_input_state("mouse_left"))
> 0.0
{
let _ = app_context
let _ = window_context
.event_loop_proxy
.send_event(UserEvent::CursorVisible(app_context.window_id, false));
let _ = app_context
.send_event(UserEvent::CursorVisible(window_context.window_id, false));
let _ = window_context
.event_loop_proxy
.send_event(UserEvent::CursorGrabMode(
app_context.window_id,
window_context.window_id,
CursorGrabMode::Locked,
));
}
if app_context.with_input_manager(|input_manager| {
if window_context.with_input_manager(|input_manager| {
input_manager.get_virtual_input_state("mouse_right")
}) > 0.0
{
let _ = app_context
let _ = window_context
.event_loop_proxy
.send_event(UserEvent::CursorVisible(app_context.window_id, true));
let _ = app_context
.send_event(UserEvent::CursorVisible(window_context.window_id, true));
let _ = window_context
.event_loop_proxy
.send_event(UserEvent::CursorGrabMode(
app_context.window_id,
window_context.window_id,
CursorGrabMode::None,
));
}
@ -227,20 +243,21 @@ impl Scene for MainScene {
fn render(
&mut self,
before_future: Box<dyn GpuFuture>,
app_context: &mut WindowContext,
world: &mut World,
window_context: &mut WindowContext,
) -> Result<Box<dyn GpuFuture>, Box<dyn Error>> {
let state = self.state.as_mut().ok_or("State not loaded")?;
let mut builder = AutoCommandBufferBuilder::primary(
app_context.command_buffer_allocator.clone(),
app_context.graphics_queue.queue_family_index(),
VulkanCommandBufferAllocator::get_from_world(world).clone(),
VulkanGraphicsQueue::get_from_world(world).queue_family_index(),
CommandBufferUsage::OneTimeSubmit,
)?;
{
let swapchain_image_view =
app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
let depth_image_view = app_context.with_renderer_mut(|renderer| {
window_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
let depth_image_view = window_context.with_renderer_mut(|renderer| {
renderer.get_additional_image_view(DEPTH_IMAGE_ID).clone()
});
let config = RenderPassConfig::default();
@ -249,23 +266,31 @@ impl Scene for MainScene {
&config,
swapchain_image_view,
Some(depth_image_view),
app_context.get_window_size(),
window_context.get_window_size(),
)?;
}
// Create camera uniform using the actual camera
let camera_uniform = Arc::new(state.camera.create_buffer(&app_context.memory_allocator)?);
let square_transform_uniform =
Transform::create_buffer(&app_context.memory_allocator, &state.square_instances)?;
let obj_transform_uniform =
Transform::create_buffer(&app_context.memory_allocator, &state.obj_instances)?;
let camera_uniform = Arc::new(
state
.camera
.create_buffer(VulkanMemoryAllocator::get_from_world(world))?,
);
let square_transform_uniform = Transform::create_buffer(
VulkanMemoryAllocator::get_from_world(world),
&state.square_instances,
)?;
let obj_transform_uniform = Transform::create_buffer(
VulkanMemoryAllocator::get_from_world(world),
&state.obj_instances,
)?;
state
.pipeline_loader
.with_pipeline::<SimplePipeline, _>(|pipeline| {
SimplePipeline::record_commands(
&mut builder,
&app_context.descriptor_set_allocator,
&VulkanDescriptorSetAllocator::get_from_world(world),
pipeline,
&state.square,
&square_transform_uniform,
@ -281,7 +306,7 @@ impl Scene for MainScene {
SimplePipeline::record_commands(
&mut builder,
&app_context.descriptor_set_allocator,
&VulkanDescriptorSetAllocator::get_from_world(world),
pipeline,
&state.obj,
&obj_transform_uniform,
@ -302,19 +327,21 @@ impl Scene for MainScene {
let command_buffer = builder.build()?;
let render_future =
before_future.then_execute(app_context.graphics_queue.clone(), command_buffer)?;
let render_future = before_future.then_execute(
VulkanGraphicsQueue::get_from_world(world).clone(),
command_buffer,
)?;
let swapchain_image_view =
app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
window_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
let input_manager_status =
app_context.with_input_manager(|input_manager| format!("{:#?}", input_manager));
let event_loop_proxy = app_context.event_loop_proxy.clone();
let delta_time = app_context.get_delta_time();
let window_id = app_context.window_id;
let window_size = app_context.get_window_size();
window_context.with_input_manager(|input_manager| format!("{:#?}", input_manager));
let event_loop_proxy = window_context.event_loop_proxy.clone();
let delta_time = window_context.get_delta_time();
let window_id = window_context.window_id;
let window_size = window_context.get_window_size();
let render_future = app_context.with_gui_mut(|gui| {
let render_future = window_context.with_gui_mut(|gui| {
gui.immediate_ui(|gui| {
let ctx = gui.context();
egui::TopBottomPanel::top("top_panel").show(&ctx, |ui| {

View file

@ -3,8 +3,12 @@ use std::error::Error;
use crate::core::app::DEPTH_IMAGE_ID;
use crate::core::app::context::WindowContext;
use crate::core::app::user_event::UserEvent;
use crate::core::render::primitives::vulkan_resource::{
VulkanCommandBufferAllocator, VulkanGraphicsQueue,
};
use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager};
use crate::core::scene::Scene;
use bevy_ecs::world::World;
use egui_winit_vulkano::egui;
use vulkano::{
command_buffer::AutoCommandBufferBuilder, command_buffer::CommandBufferUsage, sync::GpuFuture,
@ -27,9 +31,13 @@ impl Scene for SettingsScene {
self.state.is_some()
}
fn load(&mut self, app_context: &mut WindowContext) -> Result<(), Box<dyn Error>> {
let current_resolution = app_context.get_window_size();
let available_resolutions = app_context.get_available_resolutions();
fn load(
&mut self,
_world: &mut World,
window_context: &mut WindowContext,
) -> Result<(), Box<dyn Error>> {
let current_resolution = window_context.get_window_size();
let available_resolutions = window_context.get_available_resolutions();
self.state = Some(SettingsSceneState {
current_resolution,
@ -39,28 +47,33 @@ impl Scene for SettingsScene {
Ok(())
}
fn update(&mut self, _app_context: &mut WindowContext) -> Result<(), Box<dyn Error>> {
fn update(
&mut self,
_world: &mut World,
_window_context: &WindowContext,
) -> Result<(), Box<dyn Error>> {
Ok(())
}
fn render(
&mut self,
before_future: Box<dyn GpuFuture>,
app_context: &mut WindowContext,
world: &mut World,
window_context: &mut WindowContext,
) -> Result<Box<dyn GpuFuture>, Box<dyn Error>> {
let state = self.state.as_ref().ok_or("State not found")?;
let mut builder = AutoCommandBufferBuilder::primary(
app_context.command_buffer_allocator.clone(),
app_context.graphics_queue.queue_family_index(),
VulkanCommandBufferAllocator::get_from_world(world).clone(),
VulkanGraphicsQueue::get_from_world(world).queue_family_index(),
CommandBufferUsage::OneTimeSubmit,
)?;
// Utiliser le RenderPassManager
{
let swapchain_image_view =
app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
let depth_stencil_image_view = app_context.with_renderer_mut(|renderer| {
window_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
let depth_stencil_image_view = window_context.with_renderer_mut(|renderer| {
renderer.get_additional_image_view(DEPTH_IMAGE_ID).clone()
});
@ -70,7 +83,7 @@ impl Scene for SettingsScene {
&config,
swapchain_image_view,
Some(depth_stencil_image_view),
app_context.get_window_size(),
window_context.get_window_size(),
)?;
}
@ -79,16 +92,18 @@ impl Scene for SettingsScene {
let command_buffer = builder.build()?;
let render_future =
before_future.then_execute(app_context.graphics_queue.clone(), command_buffer)?;
let render_future = before_future.then_execute(
VulkanGraphicsQueue::get_from_world(world).clone(),
command_buffer,
)?;
let swapchain_image_view =
app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
window_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
let event_loop_proxy = app_context.event_loop_proxy.clone();
let window_id = app_context.window_id;
let event_loop_proxy = window_context.event_loop_proxy.clone();
let window_id = window_context.window_id;
let render_future = app_context.with_gui_mut(|gui| {
let render_future = window_context.with_gui_mut(|gui| {
gui.immediate_ui(|gui| {
let ctx = gui.context();