From 602372df5edab5664a6d2e142fcd7103222510bd Mon Sep 17 00:00:00 2001 From: John Mitchell <6656977+StarArawn@users.noreply.github.com> Date: Sat, 17 Dec 2022 16:24:52 -0500 Subject: [PATCH] Fixed examples to work with new context. --- book/src/chapter_1.md | 15 +- examples/bevy_scene.rs | 11 +- examples/clipping.rs | 8 +- examples/conditional_widget.rs | 12 +- examples/context.rs | 12 +- examples/demo.rs | 8 +- examples/hello_world.rs | 15 +- examples/hello_world_no_macro.rs | 9 +- examples/image.rs | 8 +- examples/layout.rs | 12 +- examples/main_menu.rs | 8 +- examples/multi_context.rs | 1 - examples/nine_patch.rs | 8 +- examples/quads.rs | 12 +- examples/render_target.rs | 47 +++--- examples/scrolling.rs | 12 +- examples/simple_state.rs | 12 +- examples/tabs/tabs.rs | 12 +- examples/test_no_startup.rs | 8 +- examples/text.rs | 10 +- examples/text_box.rs | 12 +- examples/texture_atlas.rs | 8 +- examples/todo/todo.rs | 12 +- examples/vec.rs | 8 +- src/camera/camera.rs | 96 ----------- src/camera/mod.rs | 46 +++--- src/camera/ortho.rs | 72 --------- src/context.rs | 2 +- src/lib.rs | 4 +- src/render/extract.rs | 30 ++-- src/render/ui_pass.rs | 262 +++++++++++++++---------------- src/render/unified/pipeline.rs | 8 +- src/render/unified/shader.wgsl | 2 +- 33 files changed, 352 insertions(+), 450 deletions(-) delete mode 100644 examples/multi_context.rs delete mode 100644 src/camera/camera.rs delete mode 100644 src/camera/ortho.rs diff --git a/book/src/chapter_1.md b/book/src/chapter_1.md index 1f8a6da..2842b93 100644 --- a/book/src/chapter_1.md +++ b/book/src/chapter_1.md @@ -19,7 +19,7 @@ fn startup( ) { font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); let parent_id = None; // The rsx! macro expects a parent_id, a widget_context from the user. @@ -37,7 +37,7 @@ fn startup( </KayakAppBundle> } - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { @@ -63,9 +63,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); commands.spawn(UICameraBundle::new()); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); let app_entity = widget_context.spawn_widget(&mut commands, None); // Create default app bundle @@ -95,9 +99,8 @@ fn startup( // Add app widget to context. widget_context.add_widget(None, app_entity); - // Add widget context as resource. - - commands.spawn(UICameraBundle::new(widget_context)); + // Spawn context as an entity. + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { App::new() diff --git a/examples/bevy_scene.rs b/examples/bevy_scene.rs index bf8439b..edea05e 100644 --- a/examples/bevy_scene.rs +++ b/examples/bevy_scene.rs @@ -115,7 +115,6 @@ fn on_color_change( /// A system that sets up the world fn world_setup(mut commands: Commands, active_color: Res<ActiveColor>) { - commands.spawn((Camera2dBundle::default(), WorldCamera)); commands .spawn(SpriteBundle { sprite: Sprite { @@ -172,9 +171,15 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { + // The UI Camera and the world camera are the same. + // CameraUIKayak is used to tell kayak which camera should render UI. + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak, WorldCamera)) + .id(); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let handle_change_color = OnEvent::new( @@ -255,7 +260,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn((UICameraBundle::new(widget_context), GameUI)); + commands.spawn((widget_context, EventDispatcher::default(), GameUI)); } fn main() { diff --git a/examples/clipping.rs b/examples/clipping.rs index 9eeb058..3620334 100644 --- a/examples/clipping.rs +++ b/examples/clipping.rs @@ -6,11 +6,15 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); + font_mapping.set_default(asset_server.load("lato-light.kttf")); let image = asset_server.load("panel.png"); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; @@ -56,7 +60,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sed tellus neque. </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/conditional_widget.rs b/examples/conditional_widget.rs index 1791f08..ca5b24b 100644 --- a/examples/conditional_widget.rs +++ b/examples/conditional_widget.rs @@ -109,13 +109,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { - font_mapping.set_default(asset_server.load("lato-light.kttf")); + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); - // Camera 2D forces a clear pass in bevy. - // We do this because our scene is not rendering anything else. - commands.spawn(Camera2dBundle::default()); + font_mapping.set_default(asset_server.load("lato-light.kttf")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; widget_context.add_widget_data::<MyWidget, MyWidgetState>(); @@ -130,7 +130,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/context.rs b/examples/context.rs index a712519..b27dd74 100644 --- a/examples/context.rs +++ b/examples/context.rs @@ -325,13 +325,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { - font_mapping.set_default(asset_server.load("roboto.kayak_font")); + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); - // Camera 2D forces a clear pass in bevy. - // We do this because our scene is not rendering anything else. - commands.spawn(Camera2dBundle::default()); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); widget_context.add_widget_data::<ThemeDemo, EmptyState>(); widget_context.add_widget_data::<ThemeButton, EmptyState>(); @@ -377,7 +377,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/demo.rs b/examples/demo.rs index 0ba501e..0d562a4 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -21,7 +21,11 @@ fn my_widget_1_render( impl Widget for MyWidget {} fn startup(mut commands: Commands) { - let mut context = KayakRootContext::new(); + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); + + let mut context = KayakRootContext::new(camera_entity); context.add_plugin(KayakWidgetsContextPlugin); context.add_widget_system( MyWidget::default().get_name(), @@ -47,7 +51,7 @@ fn startup(mut commands: Commands) { }); context.add_widget(None, app_entity); - commands.spawn(UICameraBundle::new(context)); + commands.spawn((context, EventDispatcher::default())); } // Note this example shows prop changing not state changing which is quite different. diff --git a/examples/hello_world.rs b/examples/hello_world.rs index caf0660..188504e 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -1,14 +1,23 @@ use bevy::prelude::*; -use kayak_ui::prelude::{widgets::*, *}; +use kayak_ui::{ + prelude::{widgets::*, *}, + CameraUIKayak, +}; fn startup( mut commands: Commands, mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { + let camera_entity = commands + .spawn(Camera2dBundle::default()) + .insert(CameraUIKayak) + .id(); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); + // font_mapping.force_subpixel(&asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; rsx! { @@ -23,7 +32,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/hello_world_no_macro.rs b/examples/hello_world_no_macro.rs index 1b472f8..7216668 100644 --- a/examples/hello_world_no_macro.rs +++ b/examples/hello_world_no_macro.rs @@ -5,8 +5,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { + let camera_entity = commands + .spawn(Camera2dBundle::default()) + .insert(CameraUIKayak) + .id(); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let app_entity = widget_context.spawn_widget(&mut commands, None); @@ -39,7 +44,7 @@ fn startup( // Add widget context as resource. - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { App::new() diff --git a/examples/image.rs b/examples/image.rs index ae984f6..40c7edb 100644 --- a/examples/image.rs +++ b/examples/image.rs @@ -6,11 +6,15 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); let image = asset_server.load("generic-rpg-vendor.png"); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; rsx! { @@ -30,7 +34,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/layout.rs b/examples/layout.rs index 6fdc489..f2a0e84 100644 --- a/examples/layout.rs +++ b/examples/layout.rs @@ -6,13 +6,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { - font_mapping.set_default(asset_server.load("roboto.kayak_font")); + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); - // Camera 2D forces a clear pass in bevy. - // We do this because our scene is not rendering anything else. - commands.spawn(Camera2dBundle::default()); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; @@ -130,7 +130,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/main_menu.rs b/examples/main_menu.rs index 40949d6..a66ab6b 100644 --- a/examples/main_menu.rs +++ b/examples/main_menu.rs @@ -123,9 +123,13 @@ fn startup( asset_server: Res<AssetServer>, mut preload_resource: ResMut<PreloadResource>, ) { + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); + font_mapping.set_default(asset_server.load("lato-light.kttf")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); widget_context.add_widget_data::<MenuButton, ButtonState>(); widget_context.add_widget_system( @@ -218,7 +222,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/multi_context.rs b/examples/multi_context.rs deleted file mode 100644 index 8b13789..0000000 --- a/examples/multi_context.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/examples/nine_patch.rs b/examples/nine_patch.rs index 1aeeada..ea211a7 100644 --- a/examples/nine_patch.rs +++ b/examples/nine_patch.rs @@ -6,11 +6,15 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); let image = asset_server.load("panel.png"); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; @@ -51,7 +55,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/quads.rs b/examples/quads.rs index 33216d6..6271d26 100644 --- a/examples/quads.rs +++ b/examples/quads.rs @@ -94,13 +94,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { - font_mapping.set_default(asset_server.load("roboto.kayak_font")); + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); - // Camera 2D forces a clear pass in bevy. - // We do this because our scene is not rendering anything else. - commands.spawn(Camera2dBundle::default()); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); widget_context.add_widget_system( MyQuad::default().get_name(), @@ -134,7 +134,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/render_target.rs b/examples/render_target.rs index d17bb3b..3f8fc0d 100644 --- a/examples/render_target.rs +++ b/examples/render_target.rs @@ -56,7 +56,22 @@ fn startup( let image_handle = images.add(image); - let mut widget_context = KayakRootContext::new(); + let camera_entity = commands + .spawn(Camera2dBundle { + camera: Camera { + priority: -1, + target: RenderTarget::Image(image_handle.clone()), + ..Camera::default() + }, + camera_2d: Camera2d { + clear_color: bevy::core_pipeline::clear_color::ClearColorConfig::Default, + }, + ..Default::default() + }) + .insert(CameraUIKayak) + .id(); + + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; rsx! { @@ -81,18 +96,7 @@ fn startup( /> </KayakAppBundle> }; - - commands.spawn(UICameraBundle { - camera: Camera { - priority: -1, - target: RenderTarget::Image(image_handle.clone()), - ..Camera::default() - }, - camera_ui: CameraUIKayak { - clear_color: bevy::core_pipeline::clear_color::ClearColorConfig::Default, - }, - ..UICameraBundle::new(widget_context) - }); + commands.spawn((widget_context, EventDispatcher::default())); // Setup 3D scene // Light @@ -127,14 +131,17 @@ fn startup( .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() - }); + let camera_entity = commands + .spawn(Camera3dBundle { + transform: Transform::from_translation(Vec3::new(0.0, 0.0, 15.0)) + .looking_at(Vec3::default(), Vec3::Y), + ..default() + }) + .insert(CameraUIKayak) + .id(); // Spawn another UI in 2D space! - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; rsx! { @@ -148,7 +155,7 @@ fn startup( /> </KayakAppBundle> }; - commands.spawn((UICameraBundle::new(widget_context), MainUI)); + commands.spawn((widget_context, EventDispatcher::default(), MainUI)); } /// Rotates the outer cube (main pass) diff --git a/examples/scrolling.rs b/examples/scrolling.rs index cac9c08..d77fa08 100644 --- a/examples/scrolling.rs +++ b/examples/scrolling.rs @@ -6,6 +6,10 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); + let font_asset = asset_server.load("roboto.kayak_font"); font_mapping.set_default(font_asset.clone()); @@ -14,11 +18,7 @@ fn startup( // will be ignored if this setting is used. font_mapping.force_subpixel(&font_asset); - // Camera 2D forces a clear pass in bevy. - // We do this because our scene is not rendering anything else. - commands.spawn(Camera2dBundle::default()); - - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; @@ -60,7 +60,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sed tellus neque. </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/simple_state.rs b/examples/simple_state.rs index 2e27896..05bd208 100644 --- a/examples/simple_state.rs +++ b/examples/simple_state.rs @@ -85,13 +85,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { - font_mapping.set_default(asset_server.load("lato-light.kttf")); + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); - // Camera 2D forces a clear pass in bevy. - // We do this because our scene is not rendering anything else. - commands.spawn(Camera2dBundle::default()); + font_mapping.set_default(asset_server.load("lato-light.kttf")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; widget_context.add_widget_data::<CurrentCount, CurrentCountState>(); @@ -129,7 +129,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/tabs/tabs.rs b/examples/tabs/tabs.rs index 2539aec..9ecb4b5 100644 --- a/examples/tabs/tabs.rs +++ b/examples/tabs/tabs.rs @@ -15,13 +15,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { - font_mapping.set_default(asset_server.load("roboto.kayak_font")); + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); - // Camera 2D forces a clear pass in bevy. - // We do this because our scene is not rendering anything else. - commands.spawn(Camera2dBundle::default()); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); widget_context.add_widget_data::<Tab, EmptyState>(); widget_context.add_widget_data::<TabContextProvider, EmptyState>(); @@ -87,7 +87,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/test_no_startup.rs b/examples/test_no_startup.rs index 060081e..5606281 100644 --- a/examples/test_no_startup.rs +++ b/examples/test_no_startup.rs @@ -17,9 +17,13 @@ fn second_sys( asset_server: Res<AssetServer>, mut font_mapping: ResMut<FontMapping>, ) { + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; rsx! { @@ -34,7 +38,7 @@ fn second_sys( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/text.rs b/examples/text.rs index fa49287..496023d 100644 --- a/examples/text.rs +++ b/examples/text.rs @@ -73,13 +73,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { - // Camera 2D forces a clear pass in bevy. - // We do this because our scene is not rendering anything else. - commands.spawn(Camera2dBundle::default()); + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; widget_context.add_widget_data::<MyWidgetProps, EmptyState>(); @@ -92,7 +92,7 @@ fn startup( <KayakAppBundle><MyWidgetBundle props={MyWidgetProps { foo: 0 }} /></KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn update_resource(keyboard_input: Res<Input<KeyCode>>, mut my_resource: ResMut<MyResource>) { diff --git a/examples/text_box.rs b/examples/text_box.rs index 72b2731..edb8e9f 100644 --- a/examples/text_box.rs +++ b/examples/text_box.rs @@ -88,13 +88,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { - font_mapping.set_default(asset_server.load("roboto.kayak_font")); + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); - // Camera 2D forces a clear pass in bevy. - // We do this because our scene is not rendering anything else. - commands.spawn(Camera2dBundle::default()); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); widget_context.add_widget_data::<TextBoxExample, TextBoxExampleState>(); @@ -120,7 +120,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/texture_atlas.rs b/examples/texture_atlas.rs index d4e311a..69f7d7d 100644 --- a/examples/texture_atlas.rs +++ b/examples/texture_atlas.rs @@ -6,6 +6,10 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); let image_handle = asset_server.load("texture_atlas.png"); @@ -28,7 +32,7 @@ fn startup( //The flower is in the 6(-1) row and 15 collumn let flower_index = columns * 5 + 15; - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; @@ -68,7 +72,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/todo/todo.rs b/examples/todo/todo.rs index 4f62b88..c47178f 100644 --- a/examples/todo/todo.rs +++ b/examples/todo/todo.rs @@ -53,13 +53,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { - font_mapping.set_default(asset_server.load("roboto.kayak_font")); + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); - // Camera 2D forces a clear pass in bevy. - // We do this because our scene is not rendering anything else. - commands.spawn(Camera2dBundle::default()); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); widget_context.add_widget_data::<TodoItemsProps, EmptyState>(); widget_context.add_widget_data::<TodoInputProps, EmptyState>(); @@ -99,7 +99,7 @@ fn startup( </KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/examples/vec.rs b/examples/vec.rs index fa362a7..459e579 100644 --- a/examples/vec.rs +++ b/examples/vec.rs @@ -57,9 +57,13 @@ fn startup( mut font_mapping: ResMut<FontMapping>, asset_server: Res<AssetServer>, ) { + let camera_entity = commands + .spawn((Camera2dBundle::default(), CameraUIKayak)) + .id(); + font_mapping.set_default(asset_server.load("roboto.kayak_font")); - let mut widget_context = KayakRootContext::new(); + let mut widget_context = KayakRootContext::new(camera_entity); widget_context.add_plugin(KayakWidgetsContextPlugin); let parent_id = None; widget_context.add_widget_data::<MyWidgetProps, EmptyState>(); @@ -72,7 +76,7 @@ fn startup( <KayakAppBundle><MyWidgetBundle /></KayakAppBundle> }; - commands.spawn(UICameraBundle::new(widget_context)); + commands.spawn((widget_context, EventDispatcher::default())); } fn main() { diff --git a/src/camera/camera.rs b/src/camera/camera.rs deleted file mode 100644 index f432ace..0000000 --- a/src/camera/camera.rs +++ /dev/null @@ -1,96 +0,0 @@ -use bevy::{ - core_pipeline::clear_color::ClearColorConfig, - ecs::query::QueryItem, - prelude::{Bundle, Component, GlobalTransform, Transform, With}, - render::{ - camera::{Camera, CameraProjection, CameraRenderGraph, WindowOrigin}, - extract_component::ExtractComponent, - primitives::Frustum, - view::VisibleEntities, - }, -}; - -use crate::{context::KayakRootContext, event_dispatcher::EventDispatcher}; - -use super::ortho::UIOrthographicProjection; - -/// Kayak UI's default UI camera. -#[derive(Component, Clone, Default)] -pub struct CameraUIKayak { - pub clear_color: ClearColorConfig, -} - -impl ExtractComponent for CameraUIKayak { - type Query = &'static Self; - type Filter = With<Camera>; - - fn extract_component(item: QueryItem<Self::Query>) -> Self { - item.clone() - } -} - -/// Kayak UI's default UI camera bundle. -#[derive(Bundle)] -pub struct UICameraBundle { - pub camera: Camera, - // pub camera_2d: Camera2d, - pub camera_render_graph: CameraRenderGraph, - pub orthographic_projection: UIOrthographicProjection, - pub visible_entities: VisibleEntities, - pub frustum: Frustum, - pub transform: Transform, - pub global_transform: GlobalTransform, - pub camera_ui: CameraUIKayak, - pub context: KayakRootContext, - pub event_disaptcher: EventDispatcher, -} - -impl Default for UICameraBundle { - fn default() -> Self { - Self::new(KayakRootContext::default()) - } -} - -impl UICameraBundle { - pub const UI_CAMERA: &'static str = "KAYAK_UI_CAMERA"; - pub fn new(kayak_root_context: KayakRootContext) -> Self { - // we want 0 to be "closest" and +far to be "farthest" in 2d, so we offset - // the camera's translation by far and use a right handed coordinate system - let far = 1000.0; - - let orthographic_projection = UIOrthographicProjection { - far, - window_origin: WindowOrigin::BottomLeft, - ..Default::default() - }; - - let transform = Transform::from_xyz(0.0, 0.0, far - 0.1); - - let view_projection = - orthographic_projection.get_projection_matrix() * transform.compute_matrix().inverse(); - let frustum = Frustum::from_view_projection( - &view_projection, - &transform.translation, - &transform.back(), - orthographic_projection.far(), - ); - UICameraBundle { - camera: Camera { - priority: isize::MAX - 1, - ..Default::default() - }, - camera_render_graph: CameraRenderGraph::new(bevy::core_pipeline::core_2d::graph::NAME), - orthographic_projection, - frustum, - visible_entities: VisibleEntities::default(), - transform, - // camera_2d: Camera2d::default(), - global_transform: Default::default(), - camera_ui: CameraUIKayak { - clear_color: ClearColorConfig::None, - }, - context: kayak_root_context, - event_disaptcher: EventDispatcher::new(), - } - } -} diff --git a/src/camera/mod.rs b/src/camera/mod.rs index 60e86c3..0d5c7be 100644 --- a/src/camera/mod.rs +++ b/src/camera/mod.rs @@ -1,23 +1,23 @@ -use bevy::{ - prelude::{CoreStage, Plugin}, - render::{camera::CameraProjectionPlugin, extract_component::ExtractComponentPlugin}, -}; - -mod camera; -mod ortho; - -pub use camera::{CameraUIKayak, UICameraBundle}; -pub(crate) use ortho::UIOrthographicProjection; - -pub struct KayakUICameraPlugin; - -impl Plugin for KayakUICameraPlugin { - fn build(&self, app: &mut bevy::prelude::App) { - app.add_system_to_stage( - CoreStage::PostUpdate, - bevy::render::camera::camera_system::<UIOrthographicProjection>, - ) - .add_plugin(CameraProjectionPlugin::<UIOrthographicProjection>::default()) - .add_plugin(ExtractComponentPlugin::<CameraUIKayak>::default()); - } -} +use bevy::{ + ecs::query::QueryItem, + prelude::*, + render::extract_component::{ExtractComponent, ExtractComponentPlugin}, +}; + +#[derive(Component, Default, Debug, Clone, Copy)] +pub struct CameraUIKayak; +impl ExtractComponent for CameraUIKayak { + type Query = &'static Self; + type Filter = With<Camera>; + + fn extract_component(item: QueryItem<Self::Query>) -> Self { + item.clone() + } +} + +pub struct KayakUICameraPlugin; +impl Plugin for KayakUICameraPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.add_plugin(ExtractComponentPlugin::<CameraUIKayak>::default()); + } +} diff --git a/src/camera/ortho.rs b/src/camera/ortho.rs deleted file mode 100644 index bb7a800..0000000 --- a/src/camera/ortho.rs +++ /dev/null @@ -1,72 +0,0 @@ -use bevy::ecs::reflect::ReflectComponent; -use bevy::prelude::Component; -use bevy::{ - math::Mat4, - reflect::Reflect, - render::camera::{CameraProjection, ScalingMode, WindowOrigin}, -}; - -/// Kayak UI's default orthographic projection matrix -/// This matrix uses top left as 0, 0 -/// and bottom right as width, height. -/// This projection layout is typical for most UI systems. -#[derive(Debug, Clone, Component, Reflect)] -#[reflect(Component)] -pub struct UIOrthographicProjection { - pub left: f32, - pub right: f32, - pub bottom: f32, - pub top: f32, - pub near: f32, - pub far: f32, - pub window_origin: WindowOrigin, - pub scaling_mode: ScalingMode, - pub scale: f32, -} - -impl CameraProjection for UIOrthographicProjection { - fn get_projection_matrix(&self) -> Mat4 { - Mat4::orthographic_rh( - self.left * self.scale, - self.right * self.scale, - self.bottom * self.scale, - self.top * self.scale, - // NOTE: near and far are swapped to invert the depth range from [0,1] to [1,0] - // This is for interoperability with pipelines using infinite reverse perspective projections. - self.far, - self.near, - ) - } - - fn update(&mut self, width: f32, height: f32) { - match (&self.scaling_mode, &self.window_origin) { - (ScalingMode::WindowSize, WindowOrigin::BottomLeft) => { - self.left = 0.0; - self.right = width; - self.top = 0.0; - self.bottom = height; - } - _ => {} - } - } - - fn far(&self) -> f32 { - self.far - } -} - -impl Default for UIOrthographicProjection { - fn default() -> Self { - UIOrthographicProjection { - left: -1.0, - right: 1.0, - bottom: -1.0, - top: 1.0, - near: 0.0, - far: 1000.0, - window_origin: WindowOrigin::Center, - scaling_mode: ScalingMode::WindowSize, - scale: 1.0, - } - } -} diff --git a/src/context.rs b/src/context.rs index 653b035..03c1905 100644 --- a/src/context.rs +++ b/src/context.rs @@ -64,7 +64,7 @@ type WidgetSystems = HashMap< /// }).id(); /// // Stores the kayak app widget in the widget context's tree. /// widget_context.add_widget(None, app_entity); -/// commands.spawn(UICameraBundle::new(widget_context)); +/// commands.spawn((widget_context, EventDispatcher::default())); /// } /// /// fn main() { diff --git a/src/lib.rs b/src/lib.rs index 3f478f4..02ac242 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,7 +38,7 @@ pub use camera::*; pub const DEFAULT_FONT: &str = "Kayak-Default"; pub mod prelude { - pub use crate::camera::UICameraBundle; + pub use crate::camera::*; pub use crate::children::KChildren; pub use crate::clone_component::PreviousWidget; pub use crate::context::*; @@ -53,6 +53,7 @@ pub mod prelude { pub use crate::on_change::OnChange; pub use crate::on_event::OnEvent; pub use crate::on_layout::OnLayout; + pub use crate::render::draw_ui_graph; pub use crate::render::font::FontMapping; pub use crate::styles::*; pub use crate::tree::*; @@ -62,7 +63,6 @@ pub mod prelude { pub use crate::widgets; pub use kayak_font::Alignment; pub use kayak_ui_macros::{constructor, rsx}; - pub use crate::render::draw_ui_graph; } pub use focus_tree::Focusable; diff --git a/src/render/extract.rs b/src/render/extract.rs index 3b2a2f6..8859960 100644 --- a/src/render/extract.rs +++ b/src/render/extract.rs @@ -2,12 +2,14 @@ use crate::{ context::{KayakRootContext, WidgetName}, node::Node, render_primitive::RenderPrimitive, - styles::Corner, CameraUIKayak, + styles::Corner, + CameraUIKayak, }; use bevy::{ prelude::*, - render::{Extract, RenderApp, RenderStage, view::ExtractedView, render_phase::RenderPhase}, - window::Windows, ui::TransparentUi, + render::{render_phase::RenderPhase, view::ExtractedView, Extract, RenderApp, RenderStage}, + ui::TransparentUi, + window::Windows, }; use kayak_font::KayakFont; @@ -26,8 +28,14 @@ impl Plugin for BevyKayakUIExtractPlugin { fn build(&self, app: &mut bevy::prelude::App) { let render_app = app.sub_app_mut(RenderApp); render_app.add_system_to_stage(RenderStage::Extract, extract); - render_app.add_system_to_stage(RenderStage::Extract, extract_default_ui_camera_view::<Camera2d>); - render_app.add_system_to_stage(RenderStage::Extract, extract_default_ui_camera_view::<Camera3d>); + render_app.add_system_to_stage( + RenderStage::Extract, + extract_default_ui_camera_view::<Camera2d>, + ); + render_app.add_system_to_stage( + RenderStage::Extract, + extract_default_ui_camera_view::<Camera3d>, + ); } } @@ -59,7 +67,11 @@ pub fn extract( 1.0 }; let mut new_render_primitives = context.build_render_primitives(&node_query, &widget_names); - render_primitives.extend(new_render_primitives.drain(..).map(|r| (context.camera_entity, dpi, r))); + render_primitives.extend( + new_render_primitives + .drain(..) + .map(|r| (context.camera_entity, dpi, r)), + ); } let mut extracted_quads = Vec::new(); @@ -131,15 +143,13 @@ pub fn extract( #[derive(Component)] pub struct DefaultCameraView(pub Entity); - const UI_CAMERA_TRANSFORM_OFFSET: f32 = -0.1; pub fn extract_default_ui_camera_view<T: Component>( mut commands: Commands, query: Extract<Query<(Entity, &Camera, &CameraUIKayak), With<T>>>, ) { - for (entity, camera, camera_ui) in &query { - + for (entity, camera, _camera_ui) in &query { if let (Some(logical_size), Some((physical_origin, _)), Some(physical_size)) = ( camera.logical_viewport_size(), camera.physical_viewport_rect(), @@ -171,4 +181,4 @@ pub fn extract_default_ui_camera_view<T: Component>( )); } } -} \ No newline at end of file +} diff --git a/src/render/ui_pass.rs b/src/render/ui_pass.rs index d9310bf..8873ce6 100644 --- a/src/render/ui_pass.rs +++ b/src/render/ui_pass.rs @@ -1,132 +1,130 @@ -use bevy::core_pipeline::clear_color::ClearColorConfig; -use bevy::ecs::prelude::*; -use bevy::prelude::ClearColor; -use bevy::render::render_phase::{DrawFunctionId, PhaseItem}; -use bevy::render::render_resource::CachedRenderPipelineId; -use bevy::render::{ - render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, - render_phase::{DrawFunctions, RenderPhase, TrackedRenderPass}, - render_resource::{LoadOp, Operations, RenderPassDescriptor}, - renderer::RenderContext, - view::{ExtractedView, ViewTarget}, -}; -use bevy::utils::FloatOrd; - -use crate::CameraUIKayak; - -use super::extract::DefaultCameraView; - -pub struct TransparentUI { - pub sort_key: FloatOrd, - pub entity: Entity, - pub pipeline: CachedRenderPipelineId, - pub draw_function: DrawFunctionId, -} - -impl PhaseItem for TransparentUI { - type SortKey = FloatOrd; - - #[inline] - fn sort_key(&self) -> Self::SortKey { - self.sort_key - } - - #[inline] - fn draw_function(&self) -> DrawFunctionId { - self.draw_function - } -} - -pub struct MainPassUINode { - query: QueryState< - ( - &'static RenderPhase<TransparentUI>, - &'static ViewTarget, - &'static CameraUIKayak, - ), - With<ExtractedView>, - >, - default_camera_view_query: QueryState<&'static DefaultCameraView>, -} - -impl MainPassUINode { - pub const IN_VIEW: &'static str = "view"; - - pub fn new(world: &mut World) -> Self { - Self { - query: world.query_filtered(), - default_camera_view_query: world.query(), - } - } -} - -impl Node for MainPassUINode { - fn input(&self) -> Vec<SlotInfo> { - vec![SlotInfo::new(MainPassUINode::IN_VIEW, SlotType::Entity)] - } - - fn update(&mut self, world: &mut World) { - self.query.update_archetypes(world); - self.default_camera_view_query.update_archetypes(world); - } - - fn run( - &self, - graph: &mut RenderGraphContext, - render_context: &mut RenderContext, - world: &World, - ) -> Result<(), NodeRunError> { - let input_view_entity = graph.get_input_entity(Self::IN_VIEW)?; - // adapted from bevy itself; - // see: <https://github.com/bevyengine/bevy/commit/09a3d8abe062984479bf0e99fcc1508bb722baf6> - let (transparent_phase, target, _camera_ui) = match self.query.get_manual(world, input_view_entity) - { - Ok(it) => it, - _ => return Ok(()), - }; - - let view_entity = if let Ok(default_view) = self - .default_camera_view_query - .get_manual(world, input_view_entity) - { - default_view.0 - } else { - input_view_entity - }; - - // let clear_color = world.get_resource::<ClearColor>().unwrap(); - { - let pass_descriptor = RenderPassDescriptor { - label: Some("main_transparent_pass_UI"), - color_attachments: &[Some(target.get_unsampled_color_attachment(Operations { - // load: match camera_ui.clear_color { - // ClearColorConfig::Default => { - // LoadOp::Clear(world.resource::<ClearColor>().0.into()) - // } - // ClearColorConfig::Custom(color) => LoadOp::Clear(color.into()), - // ClearColorConfig::None => LoadOp::Load, - // }, - load: LoadOp::Load, - store: true, - }))], - depth_stencil_attachment: None, - }; - - let draw_functions = world - .get_resource::<DrawFunctions<TransparentUI>>() - .unwrap(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - let mut draw_functions = draw_functions.write(); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - for item in transparent_phase.items.iter() { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } - } - - Ok(()) - } -} +use bevy::ecs::prelude::*; +use bevy::render::render_phase::{DrawFunctionId, PhaseItem}; +use bevy::render::render_resource::CachedRenderPipelineId; +use bevy::render::{ + render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, + render_phase::{DrawFunctions, RenderPhase, TrackedRenderPass}, + render_resource::{LoadOp, Operations, RenderPassDescriptor}, + renderer::RenderContext, + view::{ExtractedView, ViewTarget}, +}; +use bevy::utils::FloatOrd; + +use crate::CameraUIKayak; + +use super::extract::DefaultCameraView; + +pub struct TransparentUI { + pub sort_key: FloatOrd, + pub entity: Entity, + pub pipeline: CachedRenderPipelineId, + pub draw_function: DrawFunctionId, +} + +impl PhaseItem for TransparentUI { + type SortKey = FloatOrd; + + #[inline] + fn sort_key(&self) -> Self::SortKey { + self.sort_key + } + + #[inline] + fn draw_function(&self) -> DrawFunctionId { + self.draw_function + } +} + +pub struct MainPassUINode { + query: QueryState< + ( + &'static RenderPhase<TransparentUI>, + &'static ViewTarget, + &'static CameraUIKayak, + ), + With<ExtractedView>, + >, + default_camera_view_query: QueryState<&'static DefaultCameraView>, +} + +impl MainPassUINode { + pub const IN_VIEW: &'static str = "view"; + + pub fn new(world: &mut World) -> Self { + Self { + query: world.query_filtered(), + default_camera_view_query: world.query(), + } + } +} + +impl Node for MainPassUINode { + fn input(&self) -> Vec<SlotInfo> { + vec![SlotInfo::new(MainPassUINode::IN_VIEW, SlotType::Entity)] + } + + fn update(&mut self, world: &mut World) { + self.query.update_archetypes(world); + self.default_camera_view_query.update_archetypes(world); + } + + fn run( + &self, + graph: &mut RenderGraphContext, + render_context: &mut RenderContext, + world: &World, + ) -> Result<(), NodeRunError> { + let input_view_entity = graph.get_input_entity(Self::IN_VIEW)?; + // adapted from bevy itself; + // see: <https://github.com/bevyengine/bevy/commit/09a3d8abe062984479bf0e99fcc1508bb722baf6> + let (transparent_phase, target, _camera_ui) = + match self.query.get_manual(world, input_view_entity) { + Ok(it) => it, + _ => return Ok(()), + }; + + let view_entity = if let Ok(default_view) = self + .default_camera_view_query + .get_manual(world, input_view_entity) + { + default_view.0 + } else { + input_view_entity + }; + + // let clear_color = world.get_resource::<ClearColor>().unwrap(); + { + let pass_descriptor = RenderPassDescriptor { + label: Some("main_transparent_pass_UI"), + color_attachments: &[Some(target.get_unsampled_color_attachment(Operations { + // load: match camera_ui.clear_color { + // ClearColorConfig::Default => { + // LoadOp::Clear(world.resource::<ClearColor>().0.into()) + // } + // ClearColorConfig::Custom(color) => LoadOp::Clear(color.into()), + // ClearColorConfig::None => LoadOp::Load, + // }, + load: LoadOp::Load, + store: true, + }))], + depth_stencil_attachment: None, + }; + + let draw_functions = world + .get_resource::<DrawFunctions<TransparentUI>>() + .unwrap(); + + let render_pass = render_context + .command_encoder + .begin_render_pass(&pass_descriptor); + let mut draw_functions = draw_functions.write(); + let mut tracked_pass = TrackedRenderPass::new(render_pass); + for item in transparent_phase.items.iter() { + let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); + draw_function.draw(world, &mut tracked_pass, view_entity, item); + } + } + + Ok(()) + } +} diff --git a/src/render/unified/pipeline.rs b/src/render/unified/pipeline.rs index 5d2cfc9..fcf9c90 100644 --- a/src/render/unified/pipeline.rs +++ b/src/render/unified/pipeline.rs @@ -1,8 +1,8 @@ -use bevy::prelude::{Msaa, Rect, Resource}; +use bevy::prelude::{Rect, Resource}; use bevy::render::render_resource::{ DynamicUniformBuffer, ShaderType, SpecializedRenderPipeline, SpecializedRenderPipelines, }; -use bevy::render::view::{ViewTarget, ExtractedView}; +use bevy::render::view::{ExtractedView, ViewTarget}; use bevy::utils::FloatOrd; use bevy::{ ecs::system::{ @@ -526,7 +526,6 @@ pub fn queue_quads( mut image_bind_groups: ResMut<ImageBindGroups>, unified_pipeline: Res<UnifiedPipeline>, gpu_images: Res<RenderAssets<Image>>, - msaa: Res<Msaa>, ) { if let Some(type_binding) = sprite_meta.types_buffer.binding() { sprite_meta.types_bind_group = @@ -553,6 +552,9 @@ pub fn queue_quads( let draw_quad = draw_functions.read().get_id::<DrawUI>().unwrap(); for (camera_entity, mut transparent_phase, view) in views.iter_mut() { for (entity, quad) in extracted_sprites.iter_mut() { + if camera_entity != quad.camera_entity { + continue; + } if let Some(image_handle) = quad.image.as_ref() { if let Some(gpu_image) = gpu_images.get(image_handle) { image_bind_groups diff --git a/src/render/unified/shader.wgsl b/src/render/unified/shader.wgsl index cc6061d..ff18413 100644 --- a/src/render/unified/shader.wgsl +++ b/src/render/unified/shader.wgsl @@ -71,7 +71,7 @@ fn sample_sdf(coords: vec2<f32>, arr: i32, scale: f32) -> f32 { } fn range_curve(font_size: f32) -> f32 { - return (8.528 - 9.428 * font_size + 3.428 * pow(font_size, 2.0)) + 1.0; + return (5.128 - 6.428 * font_size + 3.428 * pow(font_size, 2.0)) + 1.0; } @fragment -- GitLab