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.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/display/components.rs b/src/display/components.rs
new file mode 100644
index 0000000..4459325
--- /dev/null
+++ b/src/display/components.rs
@@ -0,0 +1,72 @@
+use bevy::{prelude::*, render::render_resource::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages}};
+use bevy_dither_post_process::components::DitherPostProcessSettings;
+use bevy_framebuffer_extract::{components::{ExtractFramebufferBundle, FramebufferExtractDestination}, render_assets::FramebufferExtractSource};
+
+/// 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,
+ extract_framebuffer_bundle: ExtractFramebufferBundle,
+ 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(FramebufferExtractSource(image_handle.clone()));
+
+ Self {
+ _terminal_display: TerminalDisplay,
+ extract_framebuffer_bundle: ExtractFramebufferBundle {
+ source: framebuffer_extract_source,
+ dest: FramebufferExtractDestination::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()
+ }
+}