aboutsummaryrefslogtreecommitdiff
path: root/src/display/components.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/display/components.rs')
-rw-r--r--src/display/components.rs125
1 files changed, 58 insertions, 67 deletions
diff --git a/src/display/components.rs b/src/display/components.rs
index 1deb6f5..1346f50 100644
--- a/src/display/components.rs
+++ b/src/display/components.rs
@@ -1,72 +1,63 @@
-use bevy::{prelude::*, render::render_resource::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages}};
+use bevy::{
+ ecs::{
+ component::ComponentId,
+ world::DeferredWorld,
+ },
+ prelude::*,
+ render::render_resource::{
+ Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
+ },
+};
use bevy_dither_post_process::components::DitherPostProcessSettings;
-use bevy_headless_render::{components::{HeadlessRenderBundle, HeadlessRenderDestination}, render_assets::HeadlessRenderSource};
+use bevy_headless_render::components::HeadlessRenderSource;
/// Marker component for terminal display
-#[derive(Component)]
-pub struct TerminalDisplay;
-
-/// Bundle for terminal display, contains a handle to an image to be used as a render target to
-/// render to the terminal
-#[derive(Bundle)]
-pub struct TerminalDisplayBundle {
- _terminal_display: TerminalDisplay,
- _headless_render_bundle: HeadlessRenderBundle,
- _dither_post_process_settings: DitherPostProcessSettings,
- image_handle: Handle<Image>,
-}
-
-impl TerminalDisplayBundle {
- /// Create a new terminal display with the given dither level. A higher level exponentially
- /// increases the size of the bayer matrix used in the ordered dithering calculations. If in
- /// doubt, 3 is a good starting value to test with.
- pub fn new(dither_level: u32, asset_server: &AssetServer) -> Self {
- let terminal_size = crossterm::terminal::size().unwrap();
- let size = Extent3d {
- width: (terminal_size.0 as u32) * 2,
- height: (terminal_size.1 as u32) * 4,
- depth_or_array_layers: 1,
- };
-
- let mut image = Image {
- texture_descriptor: TextureDescriptor {
- label: None,
- size,
- dimension: TextureDimension::D2,
- format: TextureFormat::R8Unorm,
- mip_level_count: 1,
- sample_count: 1,
- usage: TextureUsages::TEXTURE_BINDING
- | TextureUsages::COPY_SRC
- | TextureUsages::RENDER_ATTACHMENT,
- view_formats: &[],
- },
- ..default()
- };
-
- image.resize(size);
- let image_handle = asset_server.add(image);
-
- let framebuffer_extract_source =
- asset_server.add(HeadlessRenderSource(image_handle.clone()));
-
- Self {
- _terminal_display: TerminalDisplay,
- _headless_render_bundle: HeadlessRenderBundle {
- source: framebuffer_extract_source,
- dest: HeadlessRenderDestination::default(),
- },
- image_handle,
- _dither_post_process_settings: DitherPostProcessSettings::new(
- dither_level,
- asset_server,
- ),
- }
- }
-
- /// Retrieves the handle to this display's target image. Anything written here will be
- /// displayed.
- pub fn image_handle(&self) -> Handle<Image> {
- self.image_handle.clone()
+#[derive(Component, Debug)]
+#[component(on_add = on_add_terminal_display)]
+pub struct TerminalDisplay(pub u32);
+
+fn on_add_terminal_display(mut world: DeferredWorld, entity: Entity, _id: ComponentId) {
+ let asset_server = world.get_resource::<AssetServer>().unwrap();
+ let dither_level = world.entity(entity).get::<TerminalDisplay>().unwrap().0;
+
+ let terminal_size = crossterm::terminal::size().unwrap();
+ let size = Extent3d {
+ width: (terminal_size.0 as u32) * 2,
+ height: (terminal_size.1 as u32) * 4,
+ depth_or_array_layers: 1,
+ };
+
+ let mut image = Image {
+ texture_descriptor: TextureDescriptor {
+ label: None,
+ size,
+ dimension: TextureDimension::D2,
+ format: TextureFormat::R8Unorm,
+ mip_level_count: 1,
+ sample_count: 1,
+ usage: TextureUsages::TEXTURE_BINDING
+ | TextureUsages::COPY_SRC
+ | TextureUsages::RENDER_ATTACHMENT,
+ view_formats: &[],
+ },
+ ..default()
+ };
+
+ image.resize(size);
+ let image_handle = asset_server.add(image);
+
+ let headless_render_source = HeadlessRenderSource::new(&asset_server, image_handle.clone());
+ let post_process_settings = DitherPostProcessSettings::new(dither_level, &asset_server);
+ world
+ .commands()
+ .entity(entity)
+ .insert((headless_render_source, post_process_settings));
+ if let Some(mut camera) = world.entity_mut(entity).get_mut::<Camera>() {
+ camera.target = image_handle.into();
+ } else {
+ world.commands().entity(entity).insert(Camera {
+ target: image_handle.into(),
+ ..Default::default()
+ });
}
}