From 5d45b1d8b372a495b59959d987c03ac14e095629 Mon Sep 17 00:00:00 2001 From: Ryan Butler Date: Mon, 18 Sep 2023 20:52:52 -0500 Subject: [PATCH] Worldspace UI (#23) * WIP: Begin egui-texture skill * Stuck on actually getting GpuImage * Need to fix which resources are used when * Added extract keyword to in * Now runs, but warnings about managed textures * Fixed bug where I was constantly adding render nodes * Got it working * Rename to * Updated docs * Make it unlit * Added screenshot * nit: fix space in readme --- Cargo.lock | 342 +++++++++++++++++++++ Cargo.toml | 7 + README.md | 2 +- skills/worldspace-ui/Cargo.toml | 16 + skills/worldspace-ui/README.md | 11 + skills/worldspace-ui/screenshot.png | 3 + skills/worldspace-ui/src/main.rs | 84 +++++ skills/worldspace-ui/src/render_node.rs | 88 ++++++ skills/worldspace-ui/src/render_systems.rs | 37 +++ 9 files changed, 589 insertions(+), 1 deletion(-) create mode 100644 skills/worldspace-ui/Cargo.toml create mode 100644 skills/worldspace-ui/README.md create mode 100644 skills/worldspace-ui/screenshot.png create mode 100644 skills/worldspace-ui/src/main.rs create mode 100644 skills/worldspace-ui/src/render_node.rs create mode 100644 skills/worldspace-ui/src/render_systems.rs diff --git a/Cargo.lock b/Cargo.lock index 6d43974..cbe7551 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,6 +200,25 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arboard" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac57f2b058a76363e357c056e4f74f1945bf734d37b8b3ef49066c4787dde0fc" +dependencies = [ + "clipboard-win", + "core-graphics", + "image", + "log", + "objc", + "objc-foundation", + "objc_id", + "parking_lot", + "thiserror", + "winapi", + "x11rb", +] + [[package]] name = "arrayvec" version = "0.7.4" @@ -283,6 +302,12 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" +[[package]] +name = "atomic_refcell" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112ef6b3f6cb3cb6fc5b6b494ef7a848492cff1ab0ef4de10b0f7d572861c905" + [[package]] name = "autocfg" version = "1.1.0" @@ -718,6 +743,19 @@ dependencies = [ "syn 2.0.32", ] +[[package]] +name = "bevy_egui" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a73a93a8cf6b8c744281d1b88f5b0fa278d608e909af9bbf4eb491a7cb1ad2c" +dependencies = [ + "arboard", + "bevy 0.11.2", + "egui", + "thread_local", + "webbrowser", +] + [[package]] name = "bevy_encase_derive" version = "0.11.2" @@ -768,6 +806,14 @@ dependencies = [ "syn 2.0.32", ] +[[package]] +name = "bevy_flycam" +version = "0.11.0" +source = "git+https://github.com/sburris0/bevy_flycam?branch=bevy_0.11#4ed8bcebac4210f30c7d757c3fd2fba7a1d275e2" +dependencies = [ + "bevy 0.11.2", +] + [[package]] name = "bevy_gilrs" version = "0.11.2" @@ -2081,6 +2127,17 @@ dependencies = [ "libloading 0.7.4", ] +[[package]] +name = "clipboard-win" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" +dependencies = [ + "error-code", + "str-buf", + "winapi", +] + [[package]] name = "cmake" version = "0.1.50" @@ -2352,6 +2409,49 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "ecolor" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e479a7fa3f23d4e794f8b2f8b3568dd4e47886ad1b12c9c095e141cb591eb63" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "egui" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3aef8ec3ae1b772f340170c65bf27d5b8c28f543a0116c844d2ac08d01123e7" +dependencies = [ + "ahash 0.8.3", + "epaint", + "nohash-hasher", +] + +[[package]] +name = "egui-wgpu" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33caaedd8283779c787298af23d8754a7e88421ff32e89ad0040c855fc0b0224" +dependencies = [ + "bytemuck", + "epaint", + "log", + "thiserror", + "type-map", + "wgpu", +] + +[[package]] +name = "emath" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3857d743a6e0741cdd60b622a74c7a36ea75f5f8f11b793b41d905d2c9721a4b" +dependencies = [ + "bytemuck", +] + [[package]] name = "encase" version = "0.6.1" @@ -2384,6 +2484,22 @@ dependencies = [ "syn 2.0.32", ] +[[package]] +name = "epaint" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09333964d4d57f40a85338ba3ca5ed4716070ab184dcfed966b35491c5c64f3b" +dependencies = [ + "ab_glyph", + "ahash 0.8.3", + "atomic_refcell", + "bytemuck", + "ecolor", + "emath", + "nohash-hasher", + "parking_lot", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -2399,6 +2515,16 @@ dependencies = [ "serde", ] +[[package]] +name = "error-code" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" +dependencies = [ + "libc", + "str-buf", +] + [[package]] name = "euclid" version = "0.22.9" @@ -2491,6 +2617,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -2527,6 +2662,16 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "getrandom" version = "0.2.10" @@ -2772,6 +2917,25 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "ik" version = "0.0.0" @@ -2792,6 +2956,7 @@ dependencies = [ "num-rational", "num-traits", "png", + "tiff", ] [[package]] @@ -2902,6 +3067,22 @@ dependencies = [ "walkdir", ] +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + [[package]] name = "jni-sys" version = "0.3.0" @@ -2917,6 +3098,12 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" + [[package]] name = "js-sys" version = "0.3.64" @@ -3090,6 +3277,15 @@ version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "metal" version = "0.24.0" @@ -3217,6 +3413,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", + "memoffset", ] [[package]] @@ -3230,6 +3427,12 @@ dependencies = [ "libc", ] +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + [[package]] name = "nom" version = "7.1.3" @@ -3371,6 +3574,17 @@ dependencies = [ "objc_exception", ] +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + [[package]] name = "objc-sys" version = "0.2.0-beta.2" @@ -3406,6 +3620,15 @@ dependencies = [ "cc", ] +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + [[package]] name = "object" version = "0.32.1" @@ -3895,6 +4118,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "str-buf" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" + [[package]] name = "svg_fmt" version = "0.4.1" @@ -4008,6 +4237,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tiff" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -4139,12 +4379,36 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "type-map" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f" +dependencies = [ + "rustc-hash", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + [[package]] name = "unicode-ident" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-width" version = "0.1.10" @@ -4157,6 +4421,17 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "uuid" version = "1.4.1" @@ -4294,6 +4569,29 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webbrowser" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2c79b77f525a2d670cb40619d7d9c673d09e0666f72c591ebd7861f84a87e57" +dependencies = [ + "core-foundation", + "home", + "jni 0.21.1", + "log", + "ndk-context", + "objc", + "raw-window-handle", + "url", + "web-sys", +] + +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + [[package]] name = "wgpu" version = "0.16.3" @@ -4425,6 +4723,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "winapi-wsapoll" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -4672,6 +4979,19 @@ dependencies = [ "memchr", ] +[[package]] +name = "worldspace-ui" +version = "0.0.0" +dependencies = [ + "bevy 0.11.2", + "bevy_egui", + "bevy_flycam", + "color-eyre", + "egui", + "egui-wgpu", + "wgpu", +] + [[package]] name = "x11-dl" version = "2.21.0" @@ -4683,6 +5003,28 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "x11rb" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" +dependencies = [ + "gethostname", + "nix 0.24.3", + "winapi", + "winapi-wsapoll", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67" +dependencies = [ + "nix 0.24.3", +] + [[package]] name = "xi-unicode" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index 10bfc4f..1b3549a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ resolver = "2" members = [ "skills/cube", + "skills/worldspace-ui", "skills/ik", "skills/manipulation-flatscreen", "skills/openxr-6dof", @@ -22,6 +23,12 @@ bevy_mod_picking = "0.15.0" color-eyre = "0.6" eyre = "0.6" tracing = "0.1" +bevy_egui = "0.21" +egui-wgpu = "0.22" +egui = "0.22" +bevy-inspector-egui = "0.19" +wgpu = "0.16" +bevy_flycam = { git = "https://github.com/sburris0/bevy_flycam", branch = "bevy_0.11" } # Enable a small amount of optimization in debug mode [profile.dev] diff --git a/README.md b/README.md index 4286a33..a0d5e00 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Feel free to add to the following lists: - ✅ [Single textured 3d cube](skills/cube) - 📋 Flycam camera controller - 📋 First person camera controller (for desktop users) -- 📋 In game UI ( egui, bevyui, whatever ) +- ✅ [World-space UI](skills/worldspace-ui) (with egui) - 📋 Entity inspector (`bevy_inspector_egui`) - 📋 Custom vertex and fragment shader in WGSL + bevy - ✅ [Render a GLTF/VRM model (standard shader)](skills/ik) diff --git a/skills/worldspace-ui/Cargo.toml b/skills/worldspace-ui/Cargo.toml new file mode 100644 index 0000000..e9f78cd --- /dev/null +++ b/skills/worldspace-ui/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "worldspace-ui" +version.workspace = true +license.workspace = true +repository.workspace = true +edition.workspace = true +rust-version.workspace = true + +[dependencies] +bevy.workspace = true +bevy_egui.workspace = true +bevy_flycam.workspace = true +color-eyre.workspace = true +egui-wgpu.workspace = true +egui.workspace = true +wgpu.workspace = true diff --git a/skills/worldspace-ui/README.md b/skills/worldspace-ui/README.md new file mode 100644 index 0000000..3cb020e --- /dev/null +++ b/skills/worldspace-ui/README.md @@ -0,0 +1,11 @@ +# `worldspace-ui` + +A cube that renders an [egui](https://www.egui.rs/#demo) application to a texture, +and applies it to a cube. + +To run the code: +```bash +cargo run -p worldspace-ui +``` + +![Screenshot](screenshot.png) diff --git a/skills/worldspace-ui/screenshot.png b/skills/worldspace-ui/screenshot.png new file mode 100644 index 0000000..dd8340d --- /dev/null +++ b/skills/worldspace-ui/screenshot.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0058a2533212ef4ca1c3cad1ad60eaa65e61b7bae292a3b008a1aeaf10b56681 +size 1015566 diff --git a/skills/worldspace-ui/src/main.rs b/skills/worldspace-ui/src/main.rs new file mode 100644 index 0000000..a9f9019 --- /dev/null +++ b/skills/worldspace-ui/src/main.rs @@ -0,0 +1,84 @@ +mod render_node; +mod render_systems; + +use bevy::prelude::*; +use bevy_egui::egui; +use bevy_egui::EguiContexts; +use color_eyre::Result; + +fn main() -> Result<()> { + color_eyre::install()?; + let mut app = App::new(); + app.add_plugins(DefaultPlugins) + .add_plugins(bevy_flycam::PlayerPlugin) + .add_plugins(bevy_egui::EguiPlugin) + .insert_resource(AmbientLight { + color: Color::WHITE, + brightness: 1., + }) + .add_systems(Startup, setup) + .add_systems(Update, screenspace_ui); + + let Ok(render_app) = app.get_sub_app_mut(bevy::render::RenderApp) else { + panic!("The render plugin should have added this subapp"); + }; + render_app.add_systems(ExtractSchedule, crate::render_systems::add_render_node); + + app.run(); + Ok(()) +} + +#[derive(Component, Clone)] +pub struct EguiContext { + output_texture: Handle, + ctx: egui::Context, +} + +fn setup( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, + mut images: ResMut>, +) { + let egui_thing = { + let size = wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }; + let mut output_texture = Image { + data: vec![255; (size.width * size.height * 4) as usize], + ..default() + }; + output_texture.texture_descriptor.usage |= + wgpu::TextureUsages::RENDER_ATTACHMENT; + output_texture.texture_descriptor.size = size; + let output_texture = images.add(output_texture); + + EguiContext { + output_texture, + ctx: egui::Context::default(), + } + }; + + commands.spawn(( + PbrBundle { + mesh: meshes.add(shape::Cube::default().into()), + material: materials.add(StandardMaterial { + base_color: Color::WHITE, + base_color_texture: Some(Handle::clone(&egui_thing.output_texture)), + // Remove this if you want it to use the world's lighting. + unlit: true, + ..default() + }), + ..default() + }, + egui_thing, + )); +} + +fn screenspace_ui(mut contexts: EguiContexts) { + egui::Window::new("Screenspace Window").show(contexts.ctx_mut(), |ui| { + ui.label("I am rendering to the screen!"); + }); +} diff --git a/skills/worldspace-ui/src/render_node.rs b/skills/worldspace-ui/src/render_node.rs new file mode 100644 index 0000000..07e11e0 --- /dev/null +++ b/skills/worldspace-ui/src/render_node.rs @@ -0,0 +1,88 @@ +use bevy::{prelude::*, render::render_asset::RenderAssets}; +use std::sync::Mutex; + +use crate::EguiContext; + +pub struct EguiNode { + pub output_image: Handle, + pub egui_ctx: EguiContext, + pub renderer: Mutex, +} + +impl bevy::render::render_graph::Node for EguiNode { + // TODO: When should I use this instead of an Extract render system? + fn update(&mut self, _world: &mut World) {} + + fn run( + &self, + _graph: &mut bevy::render::render_graph::RenderGraphContext, + render_context: &mut bevy::render::renderer::RenderContext, + world: &World, + ) -> Result<(), bevy::render::render_graph::NodeRunError> { + let device = render_context.render_device().clone(); + let device = device.wgpu_device(); + let queue = world + .get_resource::() + .unwrap(); + let encoder = render_context.command_encoder(); + let gpu_images = world.get_resource::>().unwrap(); + let output_gpu_image = gpu_images + .get(&self.output_image) + .expect("Should have been a `GpuImage` that corresponds to the `Image`"); + let screen_descriptor = egui_wgpu::renderer::ScreenDescriptor { + pixels_per_point: 1.0, + size_in_pixels: [ + output_gpu_image.texture.size().width, + output_gpu_image.texture.size().height, + ], + }; + + let mut renderer = self.renderer.lock().unwrap(); + + // TODO: Eventually I'll move this to a separate user defined system. + let egui_output = self.egui_ctx.ctx.run(egui::RawInput::default(), |ctx| { + egui::Window::new("Worldspace Window") + .show(ctx, |ui| ui.label("I am rendering to a texture on a cube")); + }); + // TODO: Handle textures to delete + for (tid, delta) in egui_output.textures_delta.set.iter() { + renderer.update_texture(device, queue, *tid, delta); + } + let clipped_primitives = self.egui_ctx.ctx.tessellate(egui_output.shapes); + + renderer.update_buffers( + device, + queue, + encoder, + &clipped_primitives, + &screen_descriptor, + ); + + let mut egui_render_pass = + encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("Egui Render Pass"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &output_gpu_image.texture_view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color { + r: 0.1, + g: 0.2, + b: 0.3, + a: 1.0, + }), + store: true, + }, + })], + depth_stencil_attachment: None, + }); + + renderer.render( + &mut egui_render_pass, + &clipped_primitives, + &screen_descriptor, + ); + + Ok(()) + } +} diff --git a/skills/worldspace-ui/src/render_systems.rs b/skills/worldspace-ui/src/render_systems.rs new file mode 100644 index 0000000..24f4518 --- /dev/null +++ b/skills/worldspace-ui/src/render_systems.rs @@ -0,0 +1,37 @@ +use bevy::render::Extract; +use bevy::{prelude::*, render::render_graph::RenderGraph}; + +use crate::render_node::EguiNode; +use crate::EguiContext; + +pub fn add_render_node( + q: Extract>>, + // q: Extract>, + textures: Extract>>, + mut render_graph: ResMut, + device: Res, +) { + for (entity, egui_ctx) in q.iter() { + info!("adding render node for {entity:?}"); + let output_texture_format = textures + .get(&egui_ctx.output_texture) + .expect("Should have found the matching `Image`") + .texture_descriptor + .format; + let renderer = egui_wgpu::Renderer::new( + device.wgpu_device(), + output_texture_format, + None, + 1, + ); + let new_node = EguiNode { + output_image: Handle::clone(&egui_ctx.output_texture), + renderer: renderer.into(), + egui_ctx: egui_ctx.clone(), + }; + let node_label = "egui-texture"; + render_graph.add_node(node_label, new_node); + render_graph + .add_node_edge(bevy::render::main_graph::node::CAMERA_DRIVER, node_label); + } +}