From cb4a6b760315376c3b937357c9a129492a1b42d9 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Thu, 31 Oct 2024 10:48:15 +0100 Subject: [PATCH 1/4] use RenderEntity and MainEntity Something is rendering! but still mostly broken. --- Cargo.toml | 26 +++++++++++--- examples/paint_callback.rs | 29 ++++++++-------- examples/ui.rs | 28 ++++++++++----- src/egui_node.rs | 31 ++++++++++------- src/egui_render_to_texture_node.rs | 28 +++++++++------ src/lib.rs | 2 +- src/render_systems.rs | 55 +++++++++++++++++++----------- src/systems.rs | 6 ++-- 8 files changed, 131 insertions(+), 74 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f6c42e3b..7dc1bc02 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,7 @@ name = "render_egui_to_texture" required-features = ["render"] [dependencies] -bevy = { version = "0.15.0-dev", default-features = false, features = [ +bevy = { version = "0.15.0-rc.2", default-features = false, features = [ "bevy_asset", "bevy_winit", ] } @@ -59,15 +59,18 @@ arboard = { version = "3.2.0", optional = true } thread_local = { version = "1.1.0", optional = true } [dev-dependencies] -version-sync = "0.9.4" -bevy = { version = "0.15.0-dev", default-features = false, features = [ +# 0.15.0-rc.1 +# 0.15.0-dev +bevy = { version = "0.15.0-rc.2", default-features = false, features = [ "x11", "png", "bevy_pbr", "bevy_core_pipeline", "tonemapping_luts", "webgl2", + "custom_cursor", ] } +version-sync = "0.9.4" egui = { version = "0.28", default-features = false, features = ["bytemuck"] } [target.'cfg(target_arch = "wasm32")'.dependencies] @@ -92,4 +95,19 @@ crossbeam-channel = "0.5.8" members = ["run-wasm"] [patch.crates-io] -bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "9386bd0114c44c9f00a2e9c41db1225aaa78d15" } +# doesnt work: +# bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "a2b53d46e73b98f7f5d074ed2bb8ddfedfcc5d4d" } +# doesnt work: +#bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "cab00766d99c2bf0519464a60e8a91e05c83d0fd" } +# doesnt work: +# bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "1df8238e8d8fe968d682468301ad4140c95b7604" } +# doesnt work, breakage appears here! +# bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "56f8e526dde49b4e4ad62efb7ad27bfe0bd6f617" } +# works: +# bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "01dce4742f77a572a1ef21ce8f64ce3b6d2328a8" } +# works: +# bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "7ee5143d45f9246f9cffc52e916ae12d85a71779" } +# works: +# bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "3139b03e7400313d947dc912e12d7c2d98207653" } +# works: +#bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "9386bd0114c44c9f00a2e9c41db1225aaa78d15" } diff --git a/examples/paint_callback.rs b/examples/paint_callback.rs index 8bb2b217..00da9d58 100644 --- a/examples/paint_callback.rs +++ b/examples/paint_callback.rs @@ -8,6 +8,7 @@ use bevy::{ MultisampleState, PipelineCache, PolygonMode, PrimitiveState, RenderPipelineDescriptor, SpecializedRenderPipeline, SpecializedRenderPipelines, }, + sync_world::RenderEntity, RenderApp, }, }; @@ -52,7 +53,7 @@ impl EguiBevyPaintCallbackImpl for CustomPaintCallback { fn update( &self, _info: egui::PaintCallbackInfo, - window_entity: Entity, + window_entity: RenderEntity, key: EguiPipelineKey, world: &mut World, ) { @@ -72,7 +73,7 @@ impl EguiBevyPaintCallbackImpl for CustomPaintCallback { ); world - .entity_mut(window_entity) + .entity_mut(window_entity.id()) .insert(CustomPaintPipelineIdComp { pipeline_id }); pipeline_id }, @@ -86,12 +87,13 @@ impl EguiBevyPaintCallbackImpl for CustomPaintCallback { &self, _info: egui::PaintCallbackInfo, render_pass: &mut bevy::render::render_phase::TrackedRenderPass<'pass>, - window_entity: Entity, + window_entity: RenderEntity, _key: EguiPipelineKey, world: &'pass World, ) { let Some(pipeline) = world - .get_entity(window_entity) + .get_entity(window_entity.id()) + .ok() .and_then(|entity| entity.get::()) .and_then(|comp| { world @@ -202,23 +204,22 @@ fn setup_worldspace( output_texture }); - commands.spawn(PbrBundle { - mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0).mesh()), - material: materials.add(StandardMaterial { + commands.spawn(( + Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0).mesh())), + MeshMaterial3d(materials.add(StandardMaterial { base_color: Color::WHITE, base_color_texture: Some(Handle::clone(&output_texture)), alpha_mode: AlphaMode::Blend, // Remove this if you want it to use the world's lighting. unlit: true, ..default() - }), - ..default() - }); + })), + )); commands.spawn(EguiRenderToTextureHandle(output_texture)); - commands.spawn(Camera3dBundle { - transform: Transform::from_xyz(1.5, 1.5, 1.5).looking_at(Vec3::new(0., 0., 0.), Vec3::Y), - ..default() - }); + commands.spawn(( + Camera3d::default(), + Transform::from_xyz(1.5, 1.5, 1.5).looking_at(Vec3::new(0., 0., 0.), Vec3::Y), + )); } fn ui_render_to_texture_example_system( diff --git a/examples/ui.rs b/examples/ui.rs index 98a158c8..54438d58 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -1,7 +1,8 @@ use bevy::{ + log::{Level, LogPlugin}, prelude::*, - render::view::cursor::CursorIcon, window::{PrimaryWindow, SystemCursorIcon}, + winit::cursor::CursorIcon, }; use bevy_egui::{EguiContexts, EguiPlugin, EguiSettings}; @@ -28,19 +29,30 @@ fn main() { App::new() .insert_resource(ClearColor(Color::BLACK)) .init_resource::() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - prevent_default_event_handling: false, - ..default() - }), - ..default() - })) + .add_plugins( + DefaultPlugins + .set(LogPlugin { + filter: "warn,ui=info".to_string(), + level: Level::INFO, + ..Default::default() + }) + .set(WindowPlugin { + primary_window: Some(Window { + prevent_default_event_handling: false, + ..default() + }), + ..default() + }), + ) .add_plugins(EguiPlugin) .add_systems(Startup, configure_cursor) .add_systems(Startup, configure_visuals_system) .add_systems(Startup, configure_ui_state_system) .add_systems(Update, update_ui_scale_factor_system) .add_systems(Update, ui_example_system) + .add_systems(PreUpdate, || { + info!("new frame:"); + }) .run(); } #[derive(Default, Resource)] diff --git a/src/egui_node.rs b/src/egui_node.rs index 0966e35e..45eeafc7 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -22,6 +22,7 @@ use bevy::{ VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, }, renderer::{RenderContext, RenderDevice, RenderQueue}, + sync_world::{MainEntity, RenderEntity}, texture::{ GpuImage, Image, ImageAddressMode, ImageFilterMode, ImageSampler, ImageSamplerDescriptor, @@ -192,7 +193,8 @@ pub(crate) struct EguiDraw { /// Egui render node. pub struct EguiNode { - window_entity: Entity, + window_entity_main: MainEntity, + window_entity_render: RenderEntity, vertex_data: Vec, vertex_buffer_capacity: usize, vertex_buffer: Option, @@ -206,9 +208,10 @@ pub struct EguiNode { impl EguiNode { /// Constructs Egui render node. - pub fn new(window_entity: Entity) -> Self { + pub fn new(window_entity_main: MainEntity, window_entity_render: RenderEntity) -> Self { EguiNode { - window_entity, + window_entity_main, + window_entity_render, draw_commands: Vec::new(), vertex_data: Vec::new(), vertex_buffer_capacity: 0, @@ -226,7 +229,7 @@ impl Node for EguiNode { fn update(&mut self, world: &mut World) { let Some(key) = world .get_resource::() - .and_then(|windows| windows.windows.get(&self.window_entity)) + .and_then(|windows| windows.windows.get(&self.window_entity_main.id())) .and_then(EguiPipelineKey::from_extracted_window) else { return; @@ -235,7 +238,7 @@ impl Node for EguiNode { let mut render_target_size = world.query::<(&RenderTargetSize, &mut EguiRenderOutput)>(); let Ok((window_size, mut render_output)) = - render_target_size.get_mut(world, self.window_entity) + render_target_size.get_mut(world, self.window_entity_render.id()) else { return; }; @@ -325,7 +328,9 @@ impl Node for EguiNode { index_offset += mesh.vertices.len() as u32; let texture_handle = match mesh.texture_id { - egui::TextureId::Managed(id) => EguiTextureId::Managed(self.window_entity, id), + egui::TextureId::Managed(id) => { + EguiTextureId::Managed(self.window_entity_render.id(), id) + } egui::TextureId::User(id) => EguiTextureId::User(id), }; @@ -378,7 +383,7 @@ impl Node for EguiNode { command .callback .cb() - .update(info, self.window_entity, key, world); + .update(info, self.window_entity_render, key, world); } } @@ -392,7 +397,7 @@ impl Node for EguiNode { let pipeline_cache = world.get_resource::().unwrap(); let extracted_windows = &world.get_resource::().unwrap().windows; - let extracted_window = extracted_windows.get(&self.window_entity); + let extracted_window = extracted_windows.get(&self.window_entity_main.id()); let swap_chain_texture_view = match extracted_window.and_then(|v| v.swap_chain_texture_view.as_ref()) { None => return Ok(()), @@ -446,12 +451,12 @@ impl Node for EguiNode { return Ok(()); }; - let pipeline_id = egui_pipelines.get(&self.window_entity).unwrap(); + let pipeline_id = egui_pipelines.get(&self.window_entity_main).unwrap(); let Some(pipeline) = pipeline_cache.get_render_pipeline(*pipeline_id) else { return Ok(()); }; - let transform_buffer_offset = egui_transforms.offsets[&self.window_entity]; + let transform_buffer_offset = egui_transforms.offsets[&self.window_entity_main]; let transform_buffer_bind_group = &egui_transforms.bind_group.as_ref().unwrap().1; let mut requires_reset = true; @@ -556,7 +561,7 @@ impl Node for EguiNode { command.callback.cb().render( info, &mut render_pass, - self.window_entity, + self.window_entity_render, key, world, ); @@ -666,7 +671,7 @@ pub trait EguiBevyPaintCallbackImpl: Send + Sync { fn update( &self, info: egui::PaintCallbackInfo, - window_entity: Entity, + window_entity: RenderEntity, pipeline_key: EguiPipelineKey, world: &mut World, ); @@ -679,7 +684,7 @@ pub trait EguiBevyPaintCallbackImpl: Send + Sync { &self, info: egui::PaintCallbackInfo, render_pass: &mut TrackedRenderPass<'pass>, - window_entity: Entity, + window_entity: RenderEntity, pipeline_key: EguiPipelineKey, world: &'pass World, ); diff --git a/src/egui_render_to_texture_node.rs b/src/egui_render_to_texture_node.rs index 594c1da6..39d93d49 100644 --- a/src/egui_render_to_texture_node.rs +++ b/src/egui_render_to_texture_node.rs @@ -18,6 +18,7 @@ use bevy::{ PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, StoreOp, }, renderer::{RenderContext, RenderDevice, RenderQueue}, + sync_world::{MainEntity, RenderEntity}, texture::GpuImage, }, }; @@ -34,7 +35,8 @@ pub struct EguiRenderToTexturePass { /// Egui render to texture node. pub struct EguiRenderToTextureNode { - render_to_texture_target: Entity, + render_to_texture_target_render: RenderEntity, + render_to_texture_target_main: MainEntity, vertex_data: Vec, vertex_buffer_capacity: usize, vertex_buffer: Option, @@ -47,9 +49,13 @@ pub struct EguiRenderToTextureNode { } impl EguiRenderToTextureNode { /// Constructs Egui render node. - pub fn new(render_to_texture_target: Entity) -> Self { + pub fn new( + render_to_texture_target_render: RenderEntity, + render_to_texture_target_main: MainEntity, + ) -> Self { EguiRenderToTextureNode { - render_to_texture_target, + render_to_texture_target_render, + render_to_texture_target_main, draw_commands: Vec::new(), vertex_data: Vec::new(), vertex_buffer_capacity: 0, @@ -66,7 +72,7 @@ impl Node for EguiRenderToTextureNode { fn update(&mut self, world: &mut World) { let Ok(image_handle) = world .query::<&EguiRenderToTextureHandle>() - .get(world, self.render_to_texture_target) + .get(world, self.render_to_texture_target_render.id()) .map(|handle| handle.0.clone_weak()) else { return; @@ -81,7 +87,7 @@ impl Node for EguiRenderToTextureNode { let mut render_target_sizes = world.query::<(&RenderTargetSize, &mut EguiRenderOutput)>(); let Ok((render_target_size, mut render_output)) = - render_target_sizes.get_mut(world, self.render_to_texture_target) + render_target_sizes.get_mut(world, self.render_to_texture_target_render.id()) else { return; }; @@ -173,7 +179,7 @@ impl Node for EguiRenderToTextureNode { let texture_handle = match mesh.texture_id { egui::TextureId::Managed(id) => { - EguiTextureId::Managed(self.render_to_texture_target, id) + EguiTextureId::Managed(self.render_to_texture_target_render.id(), id) } egui::TextureId::User(id) => EguiTextureId::User(id), }; @@ -227,7 +233,7 @@ impl Node for EguiRenderToTextureNode { command .callback .cb() - .update(info, self.render_to_texture_target, key, world); + .update(info, self.render_to_texture_target_render, key, world); } } @@ -241,7 +247,7 @@ impl Node for EguiRenderToTextureNode { let pipeline_cache = world.get_resource::().unwrap(); let extracted_render_to_texture: Option<&EguiRenderToTextureHandle> = - world.get(self.render_to_texture_target); + world.get(self.render_to_texture_target_render.id()); let Some(render_to_texture_gpu_image) = extracted_render_to_texture else { return Ok(()); }; @@ -286,7 +292,7 @@ impl Node for EguiRenderToTextureNode { let mut render_pass = TrackedRenderPass::new(device, render_pass); - let Some(pipeline_id) = egui_pipelines.get(&self.render_to_texture_target) else { + let Some(pipeline_id) = egui_pipelines.get(&self.render_to_texture_target_main) else { bevy::log::error!("no egui_pipeline"); return Ok(()); }; @@ -294,7 +300,7 @@ impl Node for EguiRenderToTextureNode { return Ok(()); }; - let transform_buffer_offset = egui_transforms.offsets[&self.render_to_texture_target]; + let transform_buffer_offset = egui_transforms.offsets[&self.render_to_texture_target_main]; let transform_buffer_bind_group = &egui_transforms.bind_group.as_ref().unwrap().1; let mut requires_reset = true; @@ -397,7 +403,7 @@ impl Node for EguiRenderToTextureNode { command.callback.cb().render( info, &mut render_pass, - self.render_to_texture_target, + self.render_to_texture_target_render, key, world, ); diff --git a/src/lib.rs b/src/lib.rs index 37ef5786..14512396 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,8 +121,8 @@ use bevy::{ SystemSet, With, Without, }, reflect::Reflect, - render::view::cursor::CursorIcon, window::{PrimaryWindow, Window}, + winit::cursor::CursorIcon, }; #[cfg(all( feature = "manage_clipboard", diff --git a/src/render_systems.rs b/src/render_systems.rs index bae941bc..805bf022 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -16,6 +16,7 @@ use bevy::{ DynamicUniformBuffer, PipelineCache, ShaderType, SpecializedRenderPipelines, }, renderer::{RenderDevice, RenderQueue}, + sync_world::{MainEntity, RenderEntity}, texture::GpuImage, view::ExtractedWindows, Extract, @@ -85,16 +86,16 @@ impl ExtractedEguiTextures<'_> { /// Sets up the pipeline for newly created windows. pub fn setup_new_windows_render_system( - windows: Extract>>, + windows: Extract>>, mut render_graph: ResMut, ) { - for window in windows.iter() { + for (window, render_window) in windows.iter() { let egui_pass = EguiPass { entity_index: window.index(), entity_generation: window.generation(), }; - - let new_node = EguiNode::new(window); + dbg!("setup_new_windows_render_system"); + let new_node = EguiNode::new(MainEntity::from(window), *render_window); render_graph.add_node(egui_pass.clone(), new_node); @@ -112,7 +113,12 @@ pub fn setup_new_rtt_render_system( entity_generation: render_to_texture_target.generation(), }; - let new_node = EguiRenderToTextureNode::new(render_to_texture_target); + let new_node = EguiRenderToTextureNode::new( + // FIXME: this RenderEntity is incorrect! + RenderEntity::from(render_to_texture_target), + // + MainEntity::from(render_to_texture_target), + ); render_graph.add_node(egui_rtt_pass.clone(), new_node); @@ -125,8 +131,8 @@ pub fn setup_new_rtt_render_system( pub struct EguiTransforms { /// Uniform buffer. pub buffer: DynamicUniformBuffer, - /// Offsets for each window. - pub offsets: HashMap, + /// The Entity is from the main world. + pub offsets: HashMap, /// Bind group. pub bind_group: Option<(BufferId, BindGroup)>, } @@ -160,7 +166,7 @@ impl EguiTransform { /// Prepares Egui transforms. pub fn prepare_egui_transforms_system( mut egui_transforms: ResMut, - render_target_sizes: Query<(Entity, &RenderTargetSize)>, + render_target_sizes: Query<(&MainEntity, &RenderTargetSize)>, egui_settings: Res, render_device: Res, @@ -171,14 +177,14 @@ pub fn prepare_egui_transforms_system( egui_transforms.buffer.clear(); egui_transforms.offsets.clear(); - for (window, size) in render_target_sizes.iter() { + for (window_main, size) in render_target_sizes.iter() { let offset = egui_transforms .buffer .push(&EguiTransform::from_render_target_size( *size, egui_settings.scale_factor, )); - egui_transforms.offsets.insert(window, offset); + egui_transforms.offsets.insert(*window_main, offset); } egui_transforms @@ -242,7 +248,7 @@ pub fn queue_bind_groups_system( /// Cached Pipeline IDs for the specialized instances of `EguiPipeline`. #[derive(Resource)] -pub struct EguiPipelines(pub HashMap); +pub struct EguiPipelines(pub HashMap); /// Queue [`EguiPipeline`] instances specialized on each window's swap chain texture format. pub fn queue_pipelines_system( @@ -251,26 +257,35 @@ pub fn queue_pipelines_system( mut specialized_pipelines: ResMut>, egui_pipeline: Res, windows: Res, - render_to_texture: Query<(Entity, &EguiRenderToTextureHandle)>, + render_to_texture: Query<(&MainEntity, &EguiRenderToTextureHandle)>, images: Res>, ) { - let mut pipelines: HashMap = windows + dbg!("queue_pipelines_system"); + let mut pipelines: HashMap = windows .iter() .filter_map(|(window_id, window)| { + dbg!("pipeline"); + //let window_id = render_entity.get(*window_id).ok()?.id(); + dbg!("pipeline contd"); let key = EguiPipelineKey::from_extracted_window(window)?; let pipeline_id = specialized_pipelines.specialize(&pipeline_cache, &egui_pipeline, key); - Some((*window_id, pipeline_id)) + Some((dbg!(MainEntity::from(*window_id)), pipeline_id)) }) .collect(); - pipelines.extend(render_to_texture.iter().filter_map(|(entity_id, handle)| { - let img = images.get(&handle.0)?; - let key = EguiPipelineKey::from_gpu_image(img); - let pipeline_id = specialized_pipelines.specialize(&pipeline_cache, &egui_pipeline, key); + pipelines.extend( + render_to_texture + .iter() + .filter_map(|(main_entity, handle)| { + let img = images.get(&handle.0)?; + let key = EguiPipelineKey::from_gpu_image(img); + let pipeline_id = + specialized_pipelines.specialize(&pipeline_cache, &egui_pipeline, key); - Some((entity_id, pipeline_id)) - })); + Some((dbg!(*main_entity), pipeline_id)) + }), + ); commands.insert_resource(EguiPipelines(pipelines)); } diff --git a/src/systems.rs b/src/systems.rs index 227f0963..210c099e 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -92,7 +92,7 @@ impl<'w, 's> ContextSystemParams<'w, 's> { } Err( err @ QueryEntityError::NoSuchEntity(_) - | err @ QueryEntityError::QueryDoesNotMatch(_), + | err @ QueryEntityError::QueryDoesNotMatch(_, _), ) => { log::error!("Failed to get an Egui context for a window ({window:?}): {err:?}",); None @@ -427,7 +427,7 @@ pub fn process_input_system( for mut context in context_params.contexts.iter_mut() { context.egui_input.modifiers = modifiers; - context.egui_input.time = Some(time.elapsed_seconds_f64()); + context.egui_input.time = Some(time.elapsed_secs_f64()); } // In some cases, we may skip certain events. For example, we ignore `ReceivedCharacter` events @@ -539,7 +539,7 @@ pub fn process_output_system( if let Some(mut cursor) = context.cursor { let mut set_icon = || { - *cursor = bevy::render::view::cursor::CursorIcon::System( + *cursor = bevy::winit::cursor::CursorIcon::System( egui_to_winit_cursor_icon(platform_output.cursor_icon) .unwrap_or(bevy::window::SystemCursorIcon::Default), ); From 2e825e10f8d70ac4f8700625205354abbe60e9c2 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Thu, 31 Oct 2024 11:22:39 +0100 Subject: [PATCH 2/4] fix render entity --- src/render_systems.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/render_systems.rs b/src/render_systems.rs index 7998305e..a325d4d6 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -104,19 +104,19 @@ pub fn setup_new_windows_render_system( } /// Sets up the pipeline for newly created Render to texture entities. pub fn setup_new_rtt_render_system( - render_to_texture_targets: Extract>>, + render_to_texture_targets: Extract< + Query<(Entity, &RenderEntity), Added>, + >, mut render_graph: ResMut, ) { - for render_to_texture_target in render_to_texture_targets.iter() { + for (render_to_texture_target, render_entity) in render_to_texture_targets.iter() { let egui_rtt_pass = EguiRenderToTexturePass { entity_index: render_to_texture_target.index(), entity_generation: render_to_texture_target.generation(), }; let new_node = EguiRenderToTextureNode::new( - // FIXME: this RenderEntity is incorrect! - RenderEntity::from(render_to_texture_target), - // + *render_entity, MainEntity::from(render_to_texture_target), ); From a5d827e1140d3f539e13e790db731d0b6efc7a57 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Thu, 31 Oct 2024 12:03:50 +0100 Subject: [PATCH 3/4] fix examples compiling --- examples/render_egui_to_texture.rs | 19 +++++----- examples/render_to_image_widget.rs | 57 ++++++++++++++---------------- examples/side_panel.rs | 34 ++++++++---------- examples/two_windows.rs | 10 +++--- 4 files changed, 55 insertions(+), 65 deletions(-) diff --git a/examples/render_egui_to_texture.rs b/examples/render_egui_to_texture.rs index 953ee584..dfde0f50 100644 --- a/examples/render_egui_to_texture.rs +++ b/examples/render_egui_to_texture.rs @@ -49,21 +49,20 @@ fn setup_worldspace( output_texture }); - commands.spawn(PbrBundle { - mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0).mesh()), - material: materials.add(StandardMaterial { + commands.spawn(( + Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0).mesh())), + MeshMaterial3d(materials.add(StandardMaterial { base_color: Color::WHITE, base_color_texture: Some(Handle::clone(&output_texture)), alpha_mode: AlphaMode::Blend, // Remove this if you want it to use the world's lighting. unlit: true, ..default() - }), - ..default() - }); + })), + )); commands.spawn(EguiRenderToTextureHandle(output_texture)); - commands.spawn(Camera3dBundle { - transform: Transform::from_xyz(1.5, 1.5, 1.5).looking_at(Vec3::new(0., 0., 0.), Vec3::Y), - ..default() - }); + commands.spawn(( + Camera3d::default(), + Transform::from_xyz(1.5, 1.5, 1.5).looking_at(Vec3::new(0., 0., 0.), Vec3::Y), + )); } diff --git a/examples/render_to_image_widget.rs b/examples/render_to_image_widget.rs index c782b689..39a52c23 100644 --- a/examples/render_to_image_widget.rs +++ b/examples/render_to_image_widget.rs @@ -82,37 +82,36 @@ fn setup( // The cube that will be rendered to the texture. commands - .spawn(PbrBundle { - mesh: cube_handle, - material: preview_material_handle, - transform: Transform::from_translation(Vec3::new(0.0, 0.0, 1.0)), - ..default() - }) + .spawn(( + Mesh3d(cube_handle), + MeshMaterial3d(preview_material_handle), + Transform::from_translation(Vec3::new(0.0, 0.0, 1.0)), + )) .insert(PreviewPassCube) .insert(preview_pass_layer.clone()); // The same light is reused for both passes, // you can specify different lights for preview and main pass by setting appropriate RenderLayers. commands - .spawn(PointLightBundle { - transform: Transform::from_translation(Vec3::new(0.0, 0.0, 10.0)), - ..default() - }) + .spawn(( + PointLight::default(), + Transform::from_translation(Vec3::new(0.0, 0.0, 10.0)), + )) .insert(RenderLayers::default().with(1)); commands - .spawn(Camera3dBundle { - camera: Camera { + .spawn(( + Camera3d::default(), + Camera { // render before the "main pass" camera order: -1, target: RenderTarget::Image(image_handle), clear_color: ClearColorConfig::Custom(Color::srgba(1.0, 1.0, 1.0, 0.0)), ..default() }, - transform: Transform::from_translation(Vec3::new(0.0, 0.0, 15.0)) + Transform::from_translation(Vec3::new(0.0, 0.0, 15.0)) .looking_at(Vec3::default(), Vec3::Y), - ..default() - }) + )) .insert(preview_pass_layer); let cube_size = 4.0; @@ -122,30 +121,28 @@ fn setup( // Main pass cube. commands - .spawn(PbrBundle { - mesh: cube_handle, - material: main_material_handle, - transform: Transform { + .spawn(( + Mesh3d(cube_handle), + MeshMaterial3d(main_material_handle), + Transform { translation: Vec3::new(0.0, 0.0, 1.5), rotation: Quat::from_rotation_x(-std::f32::consts::PI / 5.0), ..default() }, - ..default() - }) + )) .insert(MainPassCube); // The main pass camera. - commands.spawn(Camera3dBundle { - transform: Transform::from_translation(Vec3::new(0.0, 0.0, 15.0)) - .looking_at(Vec3::default(), Vec3::Y), - ..default() - }); + commands.spawn(( + Camera3d::default(), + Transform::from_translation(Vec3::new(0.0, 0.0, 15.0)).looking_at(Vec3::default(), Vec3::Y), + )); } fn render_to_image_example_system( cube_preview_image: Res, - preview_cube_query: Query<&Handle, With>, - main_cube_query: Query<&Handle, With>, + preview_cube_query: Query<&MeshMaterial3d, With>, + main_cube_query: Query<&MeshMaterial3d, With>, mut materials: ResMut>, mut contexts: EguiContexts, ) { @@ -225,7 +222,7 @@ fn rotator_system( mut query: Query<&mut Transform, Or<(With, With)>>, ) { for mut transform in &mut query { - transform.rotate_x(1.5 * time.delta_seconds()); - transform.rotate_z(1.3 * time.delta_seconds()); + transform.rotate_x(1.5 * time.delta_secs()); + transform.rotate_z(1.3 * time.delta_secs()); } } diff --git a/examples/side_panel.rs b/examples/side_panel.rs index 14e9c56e..4980bee2 100644 --- a/examples/side_panel.rs +++ b/examples/side_panel.rs @@ -88,36 +88,30 @@ fn setup_system( mut meshes: ResMut>, mut materials: ResMut>, ) { - commands.spawn(PbrBundle { - mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)), - material: materials.add(Color::srgb(0.3, 0.5, 0.3)), - ..Default::default() - }); - commands.spawn(PbrBundle { - mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)), - material: materials.add(Color::srgb(0.8, 0.7, 0.6)), - transform: Transform::from_xyz(0.0, 0.5, 0.0), - ..Default::default() - }); - commands.spawn(PointLightBundle { - point_light: PointLight { + commands.spawn(( + Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))), + MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))), + )); + commands.spawn(( + Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))), + MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))), + Transform::from_xyz(0.0, 0.5, 0.0), + )); + commands.spawn(( + PointLight { intensity: 1500.0, shadows_enabled: true, ..Default::default() }, - transform: Transform::from_xyz(4.0, 8.0, 4.0), - ..Default::default() - }); + Transform::from_xyz(4.0, 8.0, 4.0), + )); let camera_pos = Vec3::new(-2.0, 2.5, 5.0); let camera_transform = Transform::from_translation(camera_pos).looking_at(CAMERA_TARGET, Vec3::Y); commands.insert_resource(OriginalCameraTransform(camera_transform)); - commands.spawn(Camera3dBundle { - transform: camera_transform, - ..Default::default() - }); + commands.spawn((Camera3d::default(), camera_transform)); } fn update_camera_transform_system( diff --git a/examples/two_windows.rs b/examples/two_windows.rs index b072950f..ba6174af 100644 --- a/examples/two_windows.rs +++ b/examples/two_windows.rs @@ -35,14 +35,14 @@ fn create_new_window_system(mut commands: Commands) { .id(); // second window camera - commands.spawn(Camera3dBundle { - camera: Camera { + commands.spawn(( + Camera3d::default(), + Camera { target: RenderTarget::Window(WindowRef::Entity(second_window_id)), ..Default::default() }, - transform: Transform::from_xyz(6.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y), - ..Default::default() - }); + Transform::from_xyz(6.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y), + )); } fn load_assets_system(mut commands: Commands, assets: Res) { From d096ac826603486f0fe8674347a19aea272f4f54 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 4 Nov 2024 23:06:27 +0100 Subject: [PATCH 4/4] bunch of warns that should be removed + fixed ui rendering :D --- examples/paint_callback.rs | 1 + examples/two_windows.rs | 2 ++ src/egui_node.rs | 28 ++++++++++++++++++++++------ src/egui_render_to_texture_node.rs | 3 +-- src/render_systems.rs | 23 +++++++++++++++-------- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/examples/paint_callback.rs b/examples/paint_callback.rs index 00da9d58..a0c57c67 100644 --- a/examples/paint_callback.rs +++ b/examples/paint_callback.rs @@ -101,6 +101,7 @@ impl EguiBevyPaintCallbackImpl for CustomPaintCallback { .and_then(|cache| cache.get_render_pipeline(comp.pipeline_id)) }) else { + warn!("Could not find pipeline."); return; }; diff --git a/examples/two_windows.rs b/examples/two_windows.rs index ba6174af..6bd22110 100644 --- a/examples/two_windows.rs +++ b/examples/two_windows.rs @@ -70,6 +70,7 @@ fn ui_first_window_system( ) { let bevy_texture_id = egui_user_textures.add_image(images.bevy_icon.clone_weak()); let Ok(mut ctx) = egui_ctx.get_single_mut() else { + warn!("Could not find ctx."); return; }; egui::Window::new("First Window") @@ -100,6 +101,7 @@ fn ui_second_window_system( ) { let bevy_texture_id = egui_user_textures.add_image(images.bevy_icon.clone_weak()); let Ok(mut ctx) = egui_ctx.get_single_mut() else { + warn!("Could not find ctx(2)."); return; }; egui::Window::new("Second Window") diff --git a/src/egui_node.rs b/src/egui_node.rs index 2a02ec4e..92b0e099 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -6,7 +6,8 @@ use crate::{ }; use bevy::{ ecs::world::{FromWorld, World}, - prelude::{Entity, Handle, Resource}, + log::{info, warn}, + prelude::{Handle, Resource}, render::{ render_asset::RenderAssetUsages, render_graph::{Node, NodeRunError, RenderGraphContext}, @@ -227,11 +228,13 @@ impl EguiNode { impl Node for EguiNode { fn update(&mut self, world: &mut World) { + info!("drawing"); let Some(key) = world .get_resource::() .and_then(|windows| windows.windows.get(&self.window_entity_main.id())) .and_then(EguiPipelineKey::from_extracted_window) else { + warn!("Could not make EguiPipelineKey."); return; }; @@ -241,6 +244,7 @@ impl Node for EguiNode { let Ok((egui_settings, window_size, mut render_output)) = render_target_query.get_mut(world, self.window_entity_render.id()) else { + warn!("Could not find settings."); return; }; let window_size = *window_size; @@ -248,6 +252,8 @@ impl Node for EguiNode { self.pixels_per_point = window_size.scale_factor * egui_settings.scale_factor; if window_size.physical_width == 0.0 || window_size.physical_height == 0.0 { + warn!("small window"); + return; } @@ -285,6 +291,7 @@ impl Node for EguiNode { )) .is_empty() { + warn!("empty clip"); continue; } @@ -327,9 +334,7 @@ impl Node for EguiNode { index_offset += mesh.vertices.len() as u32; let texture_handle = match mesh.texture_id { - egui::TextureId::Managed(id) => { - EguiTextureId::Managed(self.window_entity_render.id(), id) - } + egui::TextureId::Managed(id) => EguiTextureId::Managed(self.window_entity_main, id), egui::TextureId::User(id) => EguiTextureId::User(id), }; @@ -399,7 +404,11 @@ impl Node for EguiNode { let extracted_window = extracted_windows.get(&self.window_entity_main.id()); let swap_chain_texture_view = match extracted_window.and_then(|v| v.swap_chain_texture_view.as_ref()) { - None => return Ok(()), + None => { + warn!("no extracted_window for eguinode"); + + return Ok(()); + } Some(window) => window, }; @@ -407,7 +416,10 @@ impl Node for EguiNode { let (vertex_buffer, index_buffer) = match (&self.vertex_buffer, &self.index_buffer) { (Some(vertex), Some(index)) => (vertex, index), - _ => return Ok(()), + _ => { + warn!("no vertex or index buffer for eguinode"); + return Ok(()); + } }; render_queue.write_buffer(vertex_buffer, 0, &self.vertex_data); @@ -422,6 +434,8 @@ impl Node for EguiNode { None => unreachable!(), }; let Some(key) = pipeline_key else { + warn!("no pipeline KEY for eguinode"); + return Ok(()); }; @@ -474,6 +488,7 @@ impl Node for EguiNode { let pipeline_id = egui_pipelines.get(&self.window_entity_main).unwrap(); let Some(pipeline) = pipeline_cache.get_render_pipeline(*pipeline_id) else { + warn!("no pipeline for eguinode"); return Ok(()); }; @@ -521,6 +536,7 @@ impl Node for EguiNode { physical_height, )); if scrissor_rect.is_empty() { + warn!("too small scissor"); continue; } diff --git a/src/egui_render_to_texture_node.rs b/src/egui_render_to_texture_node.rs index 9a21873e..b83fb8d0 100644 --- a/src/egui_render_to_texture_node.rs +++ b/src/egui_render_to_texture_node.rs @@ -8,7 +8,6 @@ use crate::{ }; use bevy::{ ecs::world::World, - prelude::Entity, render::{ render_asset::RenderAssets, render_graph::{Node, NodeRunError, RenderGraphContext, RenderLabel}, @@ -177,7 +176,7 @@ impl Node for EguiRenderToTextureNode { let texture_handle = match mesh.texture_id { egui::TextureId::Managed(id) => { - EguiTextureId::Managed(self.render_to_texture_target_render.id(), id) + EguiTextureId::Managed(self.render_to_texture_target_main, id) } egui::TextureId::User(id) => EguiTextureId::User(id), }; diff --git a/src/render_systems.rs b/src/render_systems.rs index a325d4d6..10fe58ab 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -43,7 +43,7 @@ impl ExtractResource for ExtractedEguiManagedTextures { #[derive(Debug, PartialEq, Eq, Hash)] pub enum EguiTextureId { /// Textures allocated via Egui. - Managed(Entity, u64), + Managed(MainEntity, u64), /// Textures allocated via Bevy. User(u64), } @@ -73,7 +73,10 @@ impl ExtractedEguiTextures<'_> { .0 .iter() .map(|(&(window, texture_id), managed_tex)| { - (EguiTextureId::Managed(window, texture_id), managed_tex.id()) + ( + EguiTextureId::Managed(MainEntity::from(window), texture_id), + managed_tex.id(), + ) }) .chain( self.user_textures @@ -91,8 +94,8 @@ pub fn setup_new_windows_render_system( ) { for (window, render_window) in windows.iter() { let egui_pass = EguiPass { - entity_index: window.index(), - entity_generation: window.generation(), + entity_index: render_window.index(), + entity_generation: render_window.generation(), }; dbg!("setup_new_windows_render_system"); let new_node = EguiNode::new(MainEntity::from(window), *render_window); @@ -166,11 +169,12 @@ impl EguiTransform { /// Prepares Egui transforms. pub fn prepare_egui_transforms_system( mut egui_transforms: ResMut, - render_targets: Query<(&MainEntity, &EguiSettings, &RenderTargetSize)>, + render_targets: Query<(Option<&MainEntity>, &EguiSettings, &RenderTargetSize)>, render_device: Res, render_queue: Res, egui_pipeline: Res, ) { + info!("prepare_egui_transforms_system"); egui_transforms.buffer.clear(); egui_transforms.offsets.clear(); @@ -181,7 +185,10 @@ pub fn prepare_egui_transforms_system( *size, egui_settings.scale_factor, )); - egui_transforms.offsets.insert(*window_main, offset); + info!(offset); + if let Some(window_main) = window_main { + egui_transforms.offsets.insert(*window_main, offset); + } } egui_transforms @@ -192,6 +199,7 @@ pub fn prepare_egui_transforms_system( match egui_transforms.bind_group { Some((id, _)) if buffer.id() == id => {} _ => { + info!("{:?}", buffer.id()); let transform_bind_group = render_device.create_bind_group( Some("egui transform bind group"), &egui_pipeline.transform_bind_group_layout, @@ -261,8 +269,6 @@ pub fn queue_pipelines_system( let mut pipelines: HashMap = windows .iter() .filter_map(|(window_id, window)| { - dbg!("pipeline"); - //let window_id = render_entity.get(*window_id).ok()?.id(); dbg!("pipeline contd"); let key = EguiPipelineKey::from_extracted_window(window)?; let pipeline_id = @@ -275,6 +281,7 @@ pub fn queue_pipelines_system( render_to_texture .iter() .filter_map(|(main_entity, handle)| { + dbg!("pipeline rtt"); let img = images.get(&handle.0)?; let key = EguiPipelineKey::from_gpu_image(img); let pipeline_id =