aboutsummaryrefslogtreecommitdiff
path: root/src/render_assets.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/render_assets.rs')
-rw-r--r--src/render_assets.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/render_assets.rs b/src/render_assets.rs
new file mode 100644
index 0000000..1615e01
--- /dev/null
+++ b/src/render_assets.rs
@@ -0,0 +1,52 @@
+use bevy::{prelude::*, render::{render_asset::{RenderAsset, RenderAssets, RenderAssetUsages, PrepareAssetError}, render_resource::{Buffer, Extent3d, BufferUsages, BufferDescriptor, TextureFormat}, renderer::RenderDevice}, ecs::system::{lifetimeless::SRes, SystemParamItem}};
+
+pub struct GpuFramebufferExtractSource {
+ pub buffer: Buffer,
+ pub source_handle: Handle<Image>,
+ pub source_size: Extent3d,
+ pub bytes_per_row: u32,
+ pub padded_bytes_per_row: u32,
+ pub format: TextureFormat,
+}
+
+#[derive(Asset, Reflect, Clone, Default)]
+pub struct FramebufferExtractSource(pub Handle<Image>);
+
+impl RenderAsset for FramebufferExtractSource {
+ type PreparedAsset = GpuFramebufferExtractSource;
+ type Param = (SRes<RenderDevice>, SRes<RenderAssets<Image>>);
+
+ fn asset_usage(&self) -> RenderAssetUsages {
+ RenderAssetUsages::default()
+ }
+
+ fn prepare_asset(
+ self,
+ (device, images): &mut SystemParamItem<Self::Param>,
+ ) -> Result<Self::PreparedAsset, PrepareAssetError<Self>> {
+
+ let Some(gpu_image) = images.get(&self.0) else {
+ warn!("Failed to get GPU image");
+ return Err(PrepareAssetError::RetryNextUpdate(self))
+ };
+
+ let size = gpu_image.texture.size();
+ let format = gpu_image.texture_format;
+ let bytes_per_row = (size.width / format.block_dimensions().0) * format.block_copy_size(None).unwrap();
+ let padded_bytes_per_row = RenderDevice::align_copy_bytes_per_row(bytes_per_row as usize) as u32;
+
+ Ok(GpuFramebufferExtractSource {
+ buffer: device.create_buffer(&BufferDescriptor {
+ label: Some("framebuffer_extract_buffer"),
+ size: (size.height * padded_bytes_per_row) as u64,
+ usage: BufferUsages::COPY_DST | BufferUsages::MAP_READ,
+ mapped_at_creation: false,
+ }),
+ source_handle: self.0.clone(),
+ source_size: size,
+ bytes_per_row,
+ padded_bytes_per_row,
+ format,
+ })
+ }
+}