diff options
Diffstat (limited to 'src/display/components.rs')
-rw-r--r-- | src/display/components.rs | 72 |
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() + } +} |