From 9edc10cbd0447dec96b6109685b2e00ce432b196 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Tue, 24 Sep 2024 13:46:41 +0200 Subject: [PATCH 01/15] update to bevy main (9386bd0) --- Cargo.toml | 9 ++++-- examples/ui.rs | 14 +++++++-- src/lib.rs | 3 ++ src/systems.rs | 80 ++++++++++++++++++++++++++------------------------ 4 files changed, 63 insertions(+), 43 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 24729c9ed..ac22b608f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,14 +45,14 @@ name = "render_egui_to_texture" required-features = ["render"] [dependencies] -bevy = { version = "0.14.0", default-features = false, features = [ +bevy = { version = "0.15.0-dev", default-features = false, features = [ "bevy_asset", "bevy_winit", ] } egui = { version = "0.28", default-features = false, features = ["bytemuck"] } bytemuck = "1" webbrowser = { version = "1.0.1", optional = true } -wgpu-types = "0.20" +wgpu-types = "22" [target.'cfg(not(any(target_arch = "wasm32", target_os = "android")))'.dependencies] arboard = { version = "3.2.0", optional = true } @@ -60,7 +60,7 @@ thread_local = { version = "1.1.0", optional = true } [dev-dependencies] version-sync = "0.9.4" -bevy = { version = "0.14.0", default-features = false, features = [ +bevy = { version = "0.15.0-dev", default-features = false, features = [ "x11", "png", "bevy_pbr", @@ -90,3 +90,6 @@ crossbeam-channel = "0.5.8" [workspace] members = ["run-wasm"] + +[patch.crates-io] +bevy = { path = "../bevy" } diff --git a/examples/ui.rs b/examples/ui.rs index b7622a0f2..98a158c84 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -1,4 +1,8 @@ -use bevy::{prelude::*, window::PrimaryWindow}; +use bevy::{ + prelude::*, + render::view::cursor::CursorIcon, + window::{PrimaryWindow, SystemCursorIcon}, +}; use bevy_egui::{EguiContexts, EguiPlugin, EguiSettings}; struct Images { @@ -23,7 +27,6 @@ impl FromWorld for Images { fn main() { App::new() .insert_resource(ClearColor(Color::BLACK)) - .insert_resource(Msaa::Sample4) .init_resource::() .add_plugins(DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { @@ -33,6 +36,7 @@ fn main() { ..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) @@ -49,6 +53,12 @@ struct UiState { is_window_open: bool, } +fn configure_cursor(mut commands: Commands, windows: Query>) { + commands + .entity(windows.single()) + .insert(CursorIcon::System(SystemCursorIcon::Default)); +} + fn configure_visuals_system(mut contexts: EguiContexts) { contexts.ctx_mut().set_visuals(egui::Visuals { window_rounding: 0.0.into(), diff --git a/src/lib.rs b/src/lib.rs index 60c7c9cdc..d4c640ef7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,6 +121,7 @@ use bevy::{ SystemSet, With, Without, }, reflect::Reflect, + render::view::cursor::CursorIcon, window::{PrimaryWindow, Window}, }; #[cfg(all( @@ -797,6 +798,8 @@ pub struct EguiContextQuery { pub render_target_size: &'static mut RenderTargetSize, /// [`Window`] component, when rendering to a window. pub window: Option<&'static mut Window>, + /// Cursor for the + pub cursor: Option<&'static mut CursorIcon>, /// [`EguiRenderToTextureHandle`] component, when rendering to a texture. #[cfg(feature = "render")] pub render_to_texture: Option<&'static mut EguiRenderToTextureHandle>, diff --git a/src/systems.rs b/src/systems.rs index 07e1d85c0..227f09639 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -537,10 +537,12 @@ pub fn process_output_system( egui_clipboard.set_contents(&platform_output.copied_text); } - if let Some(mut window) = context.window { + if let Some(mut cursor) = context.cursor { let mut set_icon = || { - window.cursor.icon = egui_to_winit_cursor_icon(platform_output.cursor_icon) - .unwrap_or(bevy::window::CursorIcon::Default); + *cursor = bevy::render::view::cursor::CursorIcon::System( + egui_to_winit_cursor_icon(platform_output.cursor_icon) + .unwrap_or(bevy::window::SystemCursorIcon::Default), + ); }; #[cfg(windows)] @@ -598,42 +600,44 @@ pub fn process_output_system( } } -fn egui_to_winit_cursor_icon(cursor_icon: egui::CursorIcon) -> Option { +fn egui_to_winit_cursor_icon( + cursor_icon: egui::CursorIcon, +) -> Option { match cursor_icon { - egui::CursorIcon::Default => Some(bevy::window::CursorIcon::Default), - egui::CursorIcon::PointingHand => Some(bevy::window::CursorIcon::Pointer), - egui::CursorIcon::ResizeHorizontal => Some(bevy::window::CursorIcon::EwResize), - egui::CursorIcon::ResizeNeSw => Some(bevy::window::CursorIcon::NeswResize), - egui::CursorIcon::ResizeNwSe => Some(bevy::window::CursorIcon::NwseResize), - egui::CursorIcon::ResizeVertical => Some(bevy::window::CursorIcon::NsResize), - egui::CursorIcon::Text => Some(bevy::window::CursorIcon::Text), - egui::CursorIcon::Grab => Some(bevy::window::CursorIcon::Grab), - egui::CursorIcon::Grabbing => Some(bevy::window::CursorIcon::Grabbing), - egui::CursorIcon::ContextMenu => Some(bevy::window::CursorIcon::ContextMenu), - egui::CursorIcon::Help => Some(bevy::window::CursorIcon::Help), - egui::CursorIcon::Progress => Some(bevy::window::CursorIcon::Progress), - egui::CursorIcon::Wait => Some(bevy::window::CursorIcon::Wait), - egui::CursorIcon::Cell => Some(bevy::window::CursorIcon::Cell), - egui::CursorIcon::Crosshair => Some(bevy::window::CursorIcon::Crosshair), - egui::CursorIcon::VerticalText => Some(bevy::window::CursorIcon::VerticalText), - egui::CursorIcon::Alias => Some(bevy::window::CursorIcon::Alias), - egui::CursorIcon::Copy => Some(bevy::window::CursorIcon::Copy), - egui::CursorIcon::Move => Some(bevy::window::CursorIcon::Move), - egui::CursorIcon::NoDrop => Some(bevy::window::CursorIcon::NoDrop), - egui::CursorIcon::NotAllowed => Some(bevy::window::CursorIcon::NotAllowed), - egui::CursorIcon::AllScroll => Some(bevy::window::CursorIcon::AllScroll), - egui::CursorIcon::ZoomIn => Some(bevy::window::CursorIcon::ZoomIn), - egui::CursorIcon::ZoomOut => Some(bevy::window::CursorIcon::ZoomOut), - egui::CursorIcon::ResizeEast => Some(bevy::window::CursorIcon::EResize), - egui::CursorIcon::ResizeSouthEast => Some(bevy::window::CursorIcon::SeResize), - egui::CursorIcon::ResizeSouth => Some(bevy::window::CursorIcon::SResize), - egui::CursorIcon::ResizeSouthWest => Some(bevy::window::CursorIcon::SwResize), - egui::CursorIcon::ResizeWest => Some(bevy::window::CursorIcon::WResize), - egui::CursorIcon::ResizeNorthWest => Some(bevy::window::CursorIcon::NwResize), - egui::CursorIcon::ResizeNorth => Some(bevy::window::CursorIcon::NResize), - egui::CursorIcon::ResizeNorthEast => Some(bevy::window::CursorIcon::NeResize), - egui::CursorIcon::ResizeColumn => Some(bevy::window::CursorIcon::ColResize), - egui::CursorIcon::ResizeRow => Some(bevy::window::CursorIcon::RowResize), + egui::CursorIcon::Default => Some(bevy::window::SystemCursorIcon::Default), + egui::CursorIcon::PointingHand => Some(bevy::window::SystemCursorIcon::Pointer), + egui::CursorIcon::ResizeHorizontal => Some(bevy::window::SystemCursorIcon::EwResize), + egui::CursorIcon::ResizeNeSw => Some(bevy::window::SystemCursorIcon::NeswResize), + egui::CursorIcon::ResizeNwSe => Some(bevy::window::SystemCursorIcon::NwseResize), + egui::CursorIcon::ResizeVertical => Some(bevy::window::SystemCursorIcon::NsResize), + egui::CursorIcon::Text => Some(bevy::window::SystemCursorIcon::Text), + egui::CursorIcon::Grab => Some(bevy::window::SystemCursorIcon::Grab), + egui::CursorIcon::Grabbing => Some(bevy::window::SystemCursorIcon::Grabbing), + egui::CursorIcon::ContextMenu => Some(bevy::window::SystemCursorIcon::ContextMenu), + egui::CursorIcon::Help => Some(bevy::window::SystemCursorIcon::Help), + egui::CursorIcon::Progress => Some(bevy::window::SystemCursorIcon::Progress), + egui::CursorIcon::Wait => Some(bevy::window::SystemCursorIcon::Wait), + egui::CursorIcon::Cell => Some(bevy::window::SystemCursorIcon::Cell), + egui::CursorIcon::Crosshair => Some(bevy::window::SystemCursorIcon::Crosshair), + egui::CursorIcon::VerticalText => Some(bevy::window::SystemCursorIcon::VerticalText), + egui::CursorIcon::Alias => Some(bevy::window::SystemCursorIcon::Alias), + egui::CursorIcon::Copy => Some(bevy::window::SystemCursorIcon::Copy), + egui::CursorIcon::Move => Some(bevy::window::SystemCursorIcon::Move), + egui::CursorIcon::NoDrop => Some(bevy::window::SystemCursorIcon::NoDrop), + egui::CursorIcon::NotAllowed => Some(bevy::window::SystemCursorIcon::NotAllowed), + egui::CursorIcon::AllScroll => Some(bevy::window::SystemCursorIcon::AllScroll), + egui::CursorIcon::ZoomIn => Some(bevy::window::SystemCursorIcon::ZoomIn), + egui::CursorIcon::ZoomOut => Some(bevy::window::SystemCursorIcon::ZoomOut), + egui::CursorIcon::ResizeEast => Some(bevy::window::SystemCursorIcon::EResize), + egui::CursorIcon::ResizeSouthEast => Some(bevy::window::SystemCursorIcon::SeResize), + egui::CursorIcon::ResizeSouth => Some(bevy::window::SystemCursorIcon::SResize), + egui::CursorIcon::ResizeSouthWest => Some(bevy::window::SystemCursorIcon::SwResize), + egui::CursorIcon::ResizeWest => Some(bevy::window::SystemCursorIcon::WResize), + egui::CursorIcon::ResizeNorthWest => Some(bevy::window::SystemCursorIcon::NwResize), + egui::CursorIcon::ResizeNorth => Some(bevy::window::SystemCursorIcon::NResize), + egui::CursorIcon::ResizeNorthEast => Some(bevy::window::SystemCursorIcon::NeResize), + egui::CursorIcon::ResizeColumn => Some(bevy::window::SystemCursorIcon::ColResize), + egui::CursorIcon::ResizeRow => Some(bevy::window::SystemCursorIcon::RowResize), egui::CursorIcon::None => None, } } From 3be113b82f8b7122b33f92467d20d2560e0d7722 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 30 Sep 2024 09:20:07 +0200 Subject: [PATCH 02/15] use git dependency for bevy --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index ac22b608f..f6c42e3ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,4 +92,4 @@ crossbeam-channel = "0.5.8" members = ["run-wasm"] [patch.crates-io] -bevy = { path = "../bevy" } +bevy = { git = "https://github.com/bevyengine/bevy.git", rev = "9386bd0114c44c9f00a2e9c41db1225aaa78d15" } From eabb701fadc24858856a146ecc2062544681c443 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 30 Sep 2024 09:31:48 +0200 Subject: [PATCH 03/15] fix unfinished doc comment --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index d4c640ef7..37ef5786d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -798,7 +798,7 @@ pub struct EguiContextQuery { pub render_target_size: &'static mut RenderTargetSize, /// [`Window`] component, when rendering to a window. pub window: Option<&'static mut Window>, - /// Cursor for the + /// [`CursorIcon`] component. pub cursor: Option<&'static mut CursorIcon>, /// [`EguiRenderToTextureHandle`] component, when rendering to a texture. #[cfg(feature = "render")] From cb4a6b760315376c3b937357c9a129492a1b42d9 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Thu, 31 Oct 2024 10:48:15 +0100 Subject: [PATCH 04/15] 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 f6c42e3ba..7dc1bc024 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 8bb2b217a..00da9d589 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 98a158c84..54438d582 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 0966e35e5..45eeafc70 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 594c1da60..39d93d49e 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 37ef5786d..145123968 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 bae941bc5..805bf0228 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 227f09639..210c099e6 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 05/15] 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 7998305e4..a325d4d67 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 06/15] 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 953ee5844..dfde0f504 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 c782b6899..39a52c239 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 14e9c56ef..4980bee23 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 b072950f5..ba6174af8 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 07/15] 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 00da9d589..a0c57c671 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 ba6174af8..6bd22110a 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 2a02ec4ec..92b0e099b 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 9a21873ec..b83fb8d07 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 a325d4d67..10fe58aba 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 = From ac5b038da62c33478df555419ffc533bb0e92837 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Tue, 5 Nov 2024 09:30:32 +0100 Subject: [PATCH 08/15] cleaner cursor handling --- Cargo.toml | 20 +------------------- examples/ui.rs | 9 --------- src/lib.rs | 3 ++- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c0d40147f..2c369eda5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ required-features = ["render"] bevy = { version = "0.15.0-rc.2", default-features = false, features = [ "bevy_asset", "bevy_winit", + "custom_cursor", ] } egui = { version = "0.29", default-features = false, features = ["bytemuck"] } bytemuck = "1" @@ -73,7 +74,6 @@ bevy = { version = "0.15.0-rc.2", default-features = false, features = [ "bevy_core_pipeline", "tonemapping_luts", "webgl2", - "custom_cursor", ] } egui = { version = "0.29", default-features = false, features = ["bytemuck"] } @@ -101,21 +101,3 @@ crossbeam-channel = "0.5.8" [workspace] members = ["run-wasm"] - -[patch.crates-io] -# 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/ui.rs b/examples/ui.rs index a9164fd24..94612528a 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -1,8 +1,6 @@ use bevy::{ log::{Level, LogPlugin}, prelude::*, - window::{PrimaryWindow, SystemCursorIcon}, - winit::cursor::CursorIcon, }; use bevy_egui::{EguiContexts, EguiPlugin, EguiSettings}; @@ -46,7 +44,6 @@ fn main() { }), ) .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) @@ -66,12 +63,6 @@ struct UiState { is_window_open: bool, } -fn configure_cursor(mut commands: Commands, windows: Query>) { - commands - .entity(windows.single()) - .insert(CursorIcon::System(SystemCursorIcon::Default)); -} - fn configure_visuals_system(mut contexts: EguiContexts) { contexts.ctx_mut().set_visuals(egui::Visuals { window_rounding: 0.0.into(), diff --git a/src/lib.rs b/src/lib.rs index f073de8f6..a5f3603ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -124,7 +124,7 @@ use bevy::{ With, Without, }, reflect::Reflect, - window::{PrimaryWindow, Window}, + window::{PrimaryWindow, SystemCursorIcon, Window}, winit::cursor::CursorIcon, }; #[cfg(all( @@ -927,6 +927,7 @@ pub fn setup_new_windows_system( EguiFullOutput::default(), EguiOutput::default(), RenderTargetSize::default(), + CursorIcon::System(SystemCursorIcon::Default), )); } } From 4237f64f68288ea0fc075719f219f200a83624d6 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Wed, 6 Nov 2024 11:19:58 +0100 Subject: [PATCH 09/15] up bevy rc to rc3 --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2c369eda5..665d7d8ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ name = "render_egui_to_texture" required-features = ["render"] [dependencies] -bevy = { version = "0.15.0-rc.2", default-features = false, features = [ +bevy = { version = "0.15.0-rc.3", default-features = false, features = [ "bevy_asset", "bevy_winit", "custom_cursor", @@ -59,7 +59,7 @@ bevy = { version = "0.15.0-rc.2", default-features = false, features = [ egui = { version = "0.29", default-features = false, features = ["bytemuck"] } bytemuck = "1" webbrowser = { version = "1.0.1", optional = true } -wgpu-types = "22" +wgpu-types = "23" [target.'cfg(not(any(target_arch = "wasm32", target_os = "android")))'.dependencies] arboard = { version = "3.2.0", optional = true } @@ -67,7 +67,7 @@ thread_local = { version = "1.1.0", optional = true } [dev-dependencies] version-sync = "0.9.4" -bevy = { version = "0.15.0-rc.2", default-features = false, features = [ +bevy = { version = "0.15.0-rc.3", default-features = false, features = [ "x11", "png", "bevy_pbr", From d79710afb7a876f96b84da7e414de46056a41caf Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Wed, 6 Nov 2024 11:30:23 +0100 Subject: [PATCH 10/15] removed a bunch of debug logs --- examples/paint_callback.rs | 1 - examples/two_windows.rs | 2 -- examples/ui.rs | 3 --- src/egui_node.rs | 26 ++++++-------------------- src/render_systems.rs | 11 ++--------- 5 files changed, 8 insertions(+), 35 deletions(-) diff --git a/examples/paint_callback.rs b/examples/paint_callback.rs index a0c57c671..00da9d589 100644 --- a/examples/paint_callback.rs +++ b/examples/paint_callback.rs @@ -101,7 +101,6 @@ 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 6bd22110a..ba6174af8 100644 --- a/examples/two_windows.rs +++ b/examples/two_windows.rs @@ -70,7 +70,6 @@ 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") @@ -101,7 +100,6 @@ 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/examples/ui.rs b/examples/ui.rs index 94612528a..6f6cc4c3d 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -48,9 +48,6 @@ fn main() { .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 92b0e099b..488b88a16 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -6,7 +6,6 @@ use crate::{ }; use bevy::{ ecs::world::{FromWorld, World}, - log::{info, warn}, prelude::{Handle, Resource}, render::{ render_asset::RenderAssetUsages, @@ -228,13 +227,11 @@ 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; }; @@ -244,7 +241,6 @@ 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; @@ -252,8 +248,6 @@ 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; } @@ -291,7 +285,6 @@ impl Node for EguiNode { )) .is_empty() { - warn!("empty clip"); continue; } @@ -405,8 +398,6 @@ impl Node for EguiNode { let swap_chain_texture_view = match extracted_window.and_then(|v| v.swap_chain_texture_view.as_ref()) { None => { - warn!("no extracted_window for eguinode"); - return Ok(()); } Some(window) => window, @@ -417,7 +408,6 @@ impl Node for EguiNode { let (vertex_buffer, index_buffer) = match (&self.vertex_buffer, &self.index_buffer) { (Some(vertex), Some(index)) => (vertex, index), _ => { - warn!("no vertex or index buffer for eguinode"); return Ok(()); } }; @@ -434,8 +424,6 @@ impl Node for EguiNode { None => unreachable!(), }; let Some(key) = pipeline_key else { - warn!("no pipeline KEY for eguinode"); - return Ok(()); }; @@ -488,7 +476,6 @@ 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(()); }; @@ -529,22 +516,21 @@ impl Node for EguiNode { }, }; - let scrissor_rect = clip_urect.intersect(bevy::math::URect::new( + let scissor_rect = clip_urect.intersect(bevy::math::URect::new( 0, 0, physical_width, physical_height, )); - if scrissor_rect.is_empty() { - warn!("too small scissor"); + if scissor_rect.is_empty() { continue; } render_pass.set_scissor_rect( - scrissor_rect.min.x, - scrissor_rect.min.y, - scrissor_rect.width(), - scrissor_rect.height(), + scissor_rect.min.x, + scissor_rect.min.y, + scissor_rect.width(), + scissor_rect.height(), ); match &draw_command.primitive { diff --git a/src/render_systems.rs b/src/render_systems.rs index 10fe58aba..c21867d16 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -97,7 +97,6 @@ pub fn setup_new_windows_render_system( 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); render_graph.add_node(egui_pass.clone(), new_node); @@ -174,7 +173,6 @@ pub fn prepare_egui_transforms_system( render_queue: Res, egui_pipeline: Res, ) { - info!("prepare_egui_transforms_system"); egui_transforms.buffer.clear(); egui_transforms.offsets.clear(); @@ -185,7 +183,6 @@ pub fn prepare_egui_transforms_system( *size, egui_settings.scale_factor, )); - info!(offset); if let Some(window_main) = window_main { egui_transforms.offsets.insert(*window_main, offset); } @@ -199,7 +196,6 @@ 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, @@ -265,15 +261,13 @@ pub fn queue_pipelines_system( render_to_texture: Query<(&MainEntity, &EguiRenderToTextureHandle)>, images: Res>, ) { - dbg!("queue_pipelines_system"); let mut pipelines: HashMap = windows .iter() .filter_map(|(window_id, window)| { - dbg!("pipeline contd"); let key = EguiPipelineKey::from_extracted_window(window)?; let pipeline_id = specialized_pipelines.specialize(&pipeline_cache, &egui_pipeline, key); - Some((dbg!(MainEntity::from(*window_id)), pipeline_id)) + Some((MainEntity::from(*window_id), pipeline_id)) }) .collect(); @@ -281,13 +275,12 @@ 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 = specialized_pipelines.specialize(&pipeline_cache, &egui_pipeline, key); - Some((dbg!(*main_entity), pipeline_id)) + Some((*main_entity, pipeline_id)) }), ); From f048ecd00c840dc57c585de74bc08414e0e9fa16 Mon Sep 17 00:00:00 2001 From: mvlabat Date: Thu, 28 Nov 2024 14:57:13 +0200 Subject: [PATCH 11/15] Fix Android CI --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 3a6e8b58b..ef08546ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,6 +97,7 @@ bevy = { version = "0.15.0-rc.3", default-features = false, features = [ "bevy_winit", "tonemapping_luts", "webgl2", + "android-game-activity", ] } egui = { version = "0.29", default-features = false, features = ["bytemuck"] } From df4a7a4d4139d7b8e1cc3cd2ab087afeac7cb881 Mon Sep 17 00:00:00 2001 From: mvlabat Date: Thu, 28 Nov 2024 15:51:02 +0200 Subject: [PATCH 12/15] Fix the check workflow for Android --- .github/workflows/check.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 3fd9e0b74..42e65a0f1 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -123,8 +123,9 @@ jobs: cache-android-cargo-${{ hashFiles('**/Cargo.toml') }} cache-android-cargo - run: | - CC=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang \ AR=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar \ + CC=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang \ + CXX=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang++ \ cargo clippy --target=aarch64-linux-android --no-default-features --all-targets --features=${{ matrix.features }} -- -D warnings clippy_ios: From 5c74c668b2179cc96d7919a245af59f9e2ead215 Mon Sep 17 00:00:00 2001 From: mvlabat Date: Sat, 30 Nov 2024 13:44:57 +0200 Subject: [PATCH 13/15] Update Bevy to 0.15 --- Cargo.toml | 33 ++++++++++++++------------- examples/paint_callback.rs | 1 + src/egui_node.rs | 6 ++--- src/egui_render_to_texture_node.rs | 1 - src/lib.rs | 36 +++++++++++++----------------- src/render_systems.rs | 3 ++- src/systems.rs | 9 ++++---- src/text_agent.rs | 8 ++----- 8 files changed, 46 insertions(+), 51 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ef08546ec..1aa593685 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,8 +21,9 @@ manage_clipboard = ["arboard", "thread_local"] open_url = ["webbrowser"] default_fonts = ["egui/default_fonts"] render = [ - "bevy_render", "bevy_asset", + "bevy_image", + "bevy_render", "encase", "bytemuck", "egui/bytemuck", @@ -59,25 +60,26 @@ required-features = ["render"] [dependencies] egui = { version = "0.29", default-features = false } -bevy_app = "0.15.0-rc.3" -bevy_derive = "0.15.0-rc.3" -bevy_ecs = "0.15.0-rc.3" -bevy_input = "0.15.0-rc.3" -bevy_log = "0.15.0-rc.3" -bevy_math = "0.15.0-rc.3" -bevy_reflect = "0.15.0-rc.3" -bevy_time = "0.15.0-rc.3" -bevy_utils = "0.15.0-rc.3" -bevy_winit = { version = "0.15.0-rc.3", features = ["custom_cursor"] } -bevy_window = "0.15.0-rc.3" +bevy_app = "0.15.0" +bevy_derive = "0.15.0" +bevy_ecs = "0.15.0" +bevy_input = "0.15.0" +bevy_log = "0.15.0" +bevy_math = "0.15.0" +bevy_reflect = "0.15.0" +bevy_time = "0.15.0" +bevy_utils = "0.15.0" +bevy_winit = { version = "0.15.0", features = ["custom_cursor"] } +bevy_window = "0.15.0" # `open_url` feature webbrowser = { version = "1.0.1", optional = true } # `render` feature bytemuck = { version = "1", optional = true } -bevy_asset = { version = "0.15.0-rc.3", optional = true } -bevy_render = { version = "0.15.0-rc.3", optional = true } +bevy_asset = { version = "0.15.0", optional = true } +bevy_image = { version = "0.15.0", optional = true } +bevy_render = { version = "0.15.0", optional = true } encase = { version = "0.10", optional = true } wgpu-types = { version = "23.0", optional = true } @@ -88,12 +90,13 @@ thread_local = { version = "1.1.0", optional = true } [dev-dependencies] version-sync = "0.9.4" -bevy = { version = "0.15.0-rc.3", default-features = false, features = [ +bevy = { version = "0.15.0", default-features = false, features = [ "x11", "png", "bevy_pbr", "bevy_core_pipeline", "bevy_asset", + "bevy_window", "bevy_winit", "tonemapping_luts", "webgl2", diff --git a/examples/paint_callback.rs b/examples/paint_callback.rs index 00da9d589..8569e21b8 100644 --- a/examples/paint_callback.rs +++ b/examples/paint_callback.rs @@ -160,6 +160,7 @@ impl SpecializedRenderPipeline for CustomPipeline { write_mask: ColorWrites::ALL, })], }), + zero_initialize_workgroup_memory: false, } } } diff --git a/src/egui_node.rs b/src/egui_node.rs index 23ba6965c..243526a75 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -9,6 +9,7 @@ use bevy_ecs::{ prelude::*, world::{FromWorld, World}, }; +use bevy_image::{Image, ImageAddressMode, ImageFilterMode, ImageSampler, ImageSamplerDescriptor}; use bevy_render::{ render_asset::RenderAssetUsages, render_graph::{Node, NodeRunError, RenderGraphContext}, @@ -25,9 +26,7 @@ use bevy_render::{ }, renderer::{RenderContext, RenderDevice, RenderQueue}, sync_world::{MainEntity, RenderEntity}, - texture::{ - GpuImage, Image, ImageAddressMode, ImageFilterMode, ImageSampler, ImageSamplerDescriptor, - }, + texture::GpuImage, view::{ExtractedWindow, ExtractedWindows}, }; use bytemuck::cast_slice; @@ -167,6 +166,7 @@ impl SpecializedRenderPipeline for EguiPipeline { depth_stencil: None, multisample: MultisampleState::default(), push_constant_ranges: vec![], + zero_initialize_workgroup_memory: false, } } } diff --git a/src/egui_render_to_texture_node.rs b/src/egui_render_to_texture_node.rs index 55d29e428..6f669bb64 100644 --- a/src/egui_render_to_texture_node.rs +++ b/src/egui_render_to_texture_node.rs @@ -19,7 +19,6 @@ use bevy_render::{ sync_world::{MainEntity, RenderEntity}, texture::GpuImage, }; - use bytemuck::cast_slice; /// [`RenderLabel`] type for the Egui Render to Texture pass. diff --git a/src/lib.rs b/src/lib.rs index f412a4f5e..2b22a24d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -79,10 +79,14 @@ mod text_agent; ))] pub mod web_clipboard; -use bevy_winit::cursor::CursorIcon; pub use egui; use crate::systems::*; +#[cfg(target_arch = "wasm32")] +use crate::text_agent::{ + install_text_agent, is_mobile_safari, process_safari_virtual_keyboard, propagate_text, + SafariVirtualKeyboardHack, TextAgentChannel, VirtualTouchInfo, +}; #[cfg(feature = "render")] use crate::{ egui_node::{EguiPipeline, EGUI_SHADER_HANDLE}, @@ -93,19 +97,9 @@ use crate::{ not(any(target_arch = "wasm32", target_os = "android")) ))] use arboard::Clipboard; - +use bevy_app::prelude::*; #[cfg(feature = "render")] use bevy_asset::{load_internal_asset, AssetEvent, Assets, Handle}; -#[cfg(feature = "render")] -use bevy_render::{ - extract_component::{ExtractComponent, ExtractComponentPlugin}, - extract_resource::{ExtractResource, ExtractResourcePlugin}, - render_resource::SpecializedRenderPipelines, - texture::{Image, ImageSampler}, - ExtractSchedule, Render, RenderApp, RenderSet, -}; - -use bevy_app::prelude::*; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ prelude::*, @@ -113,25 +107,27 @@ use bevy_ecs::{ schedule::apply_deferred, system::SystemParam, }; +#[cfg(feature = "render")] +use bevy_image::{Image, ImageSampler}; use bevy_input::InputSystem; use bevy_reflect::Reflect; +#[cfg(feature = "render")] +use bevy_render::{ + extract_component::{ExtractComponent, ExtractComponentPlugin}, + extract_resource::{ExtractResource, ExtractResourcePlugin}, + render_resource::SpecializedRenderPipelines, + ExtractSchedule, Render, RenderApp, RenderSet, +}; use bevy_window::{PrimaryWindow, SystemCursorIcon, Window}; - +use bevy_winit::cursor::CursorIcon; #[cfg(all( feature = "manage_clipboard", not(any(target_arch = "wasm32", target_os = "android")) ))] use std::cell::{RefCell, RefMut}; - #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; -#[cfg(target_arch = "wasm32")] -use crate::text_agent::{ - install_text_agent, is_mobile_safari, process_safari_virtual_keyboard, propagate_text, - SafariVirtualKeyboardHack, TextAgentChannel, VirtualTouchInfo, -}; - /// Adds all Egui resources and render graph nodes. pub struct EguiPlugin; diff --git a/src/render_systems.rs b/src/render_systems.rs index b39a942ed..ce33b7bee 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -7,6 +7,7 @@ use crate::{ use bevy_asset::prelude::*; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{prelude::*, system::SystemParam}; +use bevy_image::Image; use bevy_math::Vec2; use bevy_render::{ extract_resource::ExtractResource, @@ -18,7 +19,7 @@ use bevy_render::{ }, renderer::{RenderDevice, RenderQueue}, sync_world::{MainEntity, RenderEntity}, - texture::{GpuImage, Image}, + texture::GpuImage, view::ExtractedWindows, Extract, }; diff --git a/src/systems.rs b/src/systems.rs index 9f23e51b2..9abe1c570 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -6,12 +6,16 @@ use crate::{ EguiContext, EguiContextQuery, EguiContextQueryItem, EguiFullOutput, EguiInput, EguiSettings, RenderTargetSize, }; +#[cfg(feature = "render")] +use bevy_asset::Assets; use bevy_ecs::{ event::EventWriter, prelude::*, query::QueryEntityError, system::{Local, Res, SystemParam}, }; +#[cfg(feature = "render")] +use bevy_image::Image; use bevy_input::{ keyboard::{Key, KeyCode, KeyboardFocusLost, KeyboardInput}, mouse::{MouseButton, MouseButtonInput, MouseScrollUnit, MouseWheel}, @@ -22,11 +26,6 @@ use bevy_log::{self, error}; use bevy_time::{Real, Time}; use bevy_window::{CursorMoved, Ime, RequestRedraw}; use bevy_winit::{EventLoopProxy, WakeUp}; - -#[cfg(feature = "render")] -use bevy_asset::Assets; -#[cfg(feature = "render")] -use bevy_render::texture::Image; use std::{marker::PhantomData, time::Duration}; #[allow(missing_docs)] diff --git a/src/text_agent.rs b/src/text_agent.rs index 963ede143..658a2bc54 100644 --- a/src/text_agent.rs +++ b/src/text_agent.rs @@ -1,17 +1,13 @@ //! The text agent is an `` element used to trigger //! mobile keyboard and IME input. -use std::sync::{LazyLock, Mutex}; - +use crate::{systems::ContextSystemParams, EventClosure, SubscribedEvents}; use bevy_ecs::prelude::*; use bevy_window::RequestRedraw; - use crossbeam_channel::{unbounded, Receiver, Sender}; - +use std::sync::{LazyLock, Mutex}; use wasm_bindgen::prelude::*; -use crate::{systems::ContextSystemParams, EventClosure, SubscribedEvents}; - static AGENT_ID: &str = "egui_text_agent"; #[allow(missing_docs)] From 4e4b8786dd9bbab00320c160486a92ffa4d84442 Mon Sep 17 00:00:00 2001 From: mvlabat Date: Sat, 30 Nov 2024 14:00:18 +0200 Subject: [PATCH 14/15] Fix wasm deprecation warning --- src/text_agent.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/text_agent.rs b/src/text_agent.rs index 658a2bc54..9e46f7a68 100644 --- a/src/text_agent.rs +++ b/src/text_agent.rs @@ -96,7 +96,9 @@ pub fn install_text_agent( .expect("failed input type coercion"); let input = std::rc::Rc::new(input); input.set_type("text"); - input.set_autofocus(true); + if let Err(err) = (&input as &web_sys::HtmlElement).set_autofocus(true) { + log::warn!("Failed to set input autofocus: {err:?}"); + } input .set_attribute("autocapitalize", "off") .expect("failed to turn off autocapitalize"); @@ -134,7 +136,9 @@ pub fn install_text_agent( } // Set size as small as possible, in case user may click on it. input.set_size(1); - input.set_autofocus(true); + if let Err(err) = (&input as &web_sys::HtmlElement).set_autofocus(true) { + log::warn!("Failed to set input autofocus: {err:?}"); + } input.set_hidden(true); let sender = text_agent_channel.sender.clone(); From 517447a4350fe270a8369564cf4d4fef658ef007 Mon Sep 17 00:00:00 2001 From: mvlabat Date: Sat, 30 Nov 2024 14:05:17 +0200 Subject: [PATCH 15/15] Bump web-sys version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1aa593685..9bad705b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ egui = { version = "0.29", default-features = false, features = ["bytemuck"] } [target.'cfg(target_arch = "wasm32")'.dependencies] winit = "0.30" -web-sys = { version = "0.3.63", features = [ +web-sys = { version = "0.3.74", features = [ "Clipboard", "ClipboardEvent", "CompositionEvent",