aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components.rs20
-rw-r--r--src/lib.rs33
-rw-r--r--src/nodes.rs16
-rw-r--r--src/render_assets.rs35
-rw-r--r--src/systems.rs14
5 files changed, 57 insertions, 61 deletions
diff --git a/src/components.rs b/src/components.rs
index f9fe912..8e25530 100644
--- a/src/components.rs
+++ b/src/components.rs
@@ -2,18 +2,18 @@ use std::sync::{Arc, Mutex};
use bevy::{ecs::query::QueryItem, prelude::*, render::extract_component::ExtractComponent};
-use crate::render_assets::FramebufferExtractSource;
+use crate::render_assets::HeadlessRenderSource;
-/// Framebuffer extraction destination. Contains the image which the framebuffer is extracted to.
+/// Headless render destination. Contains the image which the rendered frame is copied to.
#[derive(Component, Default, Clone)]
-pub struct FramebufferExtractDestination(pub Arc<Mutex<Image>>);
+pub struct HeadlessRenderDestination(pub Arc<Mutex<Image>>);
-impl ExtractComponent for FramebufferExtractDestination {
- type QueryData = (&'static Self, &'static Handle<FramebufferExtractSource>);
+impl ExtractComponent for HeadlessRenderDestination {
+ type QueryData = (&'static Self, &'static Handle<HeadlessRenderSource>);
type QueryFilter = ();
- type Out = (Self, Handle<FramebufferExtractSource>);
+ type Out = (Self, Handle<HeadlessRenderSource>);
fn extract_component(
(destination, source_handle): QueryItem<'_, Self::QueryData>,
@@ -22,11 +22,11 @@ impl ExtractComponent for FramebufferExtractDestination {
}
}
-/// Bundle containing both a source and destination for framebuffer extraction.
+/// Bundle containing both a source and destination for headless rendering.
#[derive(Bundle)]
-pub struct ExtractFramebufferBundle {
+pub struct HeadlessRenderBundle {
/// Source
- pub source: Handle<FramebufferExtractSource>,
+ pub source: Handle<HeadlessRenderSource>,
/// Destination
- pub dest: FramebufferExtractDestination,
+ pub dest: HeadlessRenderDestination,
}
diff --git a/src/lib.rs b/src/lib.rs
index 29a5896..9fadebe 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,7 +1,6 @@
#![warn(missing_docs)]
-//! Plugin for the Bevy game engine which provides the ability to extract the frambuffer image after rendering
-//! to use for whatever you want.
+//! Plugin for the Bevy game engine which provides the ability to render to an image headlessly.
use bevy::{
prelude::*,
@@ -10,9 +9,9 @@ use bevy::{
render_asset::RenderAssetPlugin, render_graph::RenderGraph, Render, RenderApp, RenderSet,
},
};
-use components::FramebufferExtractDestination;
-use nodes::{FramebufferExtractLabel, FramebufferExtractNode};
-use render_assets::FramebufferExtractSource;
+use components::HeadlessRenderDestination;
+use nodes::{HeadlessRenderCopyLabel, HeadlessRenderCopyNode};
+use render_assets::{HeadlessRenderSource, GpuHeadlessRenderSource};
/// Components used by this plugin.
pub mod components;
@@ -22,28 +21,28 @@ pub mod render_assets;
mod nodes;
mod systems;
-/// Plugin which handles framebuffer extraction.
-pub struct FramebufferExtractPlugin;
+/// Plugin which handles headless rendering.
+pub struct HeadlessRenderPlugin;
-impl Plugin for FramebufferExtractPlugin {
+impl Plugin for HeadlessRenderPlugin {
fn build(&self, app: &mut App) {
- app.register_type::<FramebufferExtractSource>()
- .init_asset::<FramebufferExtractSource>()
- .register_asset_reflect::<FramebufferExtractSource>()
+ app.register_type::<HeadlessRenderSource>()
+ .init_asset::<HeadlessRenderSource>()
+ .register_asset_reflect::<HeadlessRenderSource>()
.add_plugins((
- RenderAssetPlugin::<FramebufferExtractSource>::default(),
- ExtractComponentPlugin::<FramebufferExtractDestination>::default(),
+ RenderAssetPlugin::<GpuHeadlessRenderSource>::default(),
+ ExtractComponentPlugin::<HeadlessRenderDestination>::default(),
));
let render_app = app.sub_app_mut(RenderApp);
render_app.add_systems(
Render,
- systems::extract_framebuffers
+ systems::copy_buffers
.after(RenderSet::Render)
.before(RenderSet::Cleanup),
);
- let mut graph = render_app.world.resource_mut::<RenderGraph>();
- graph.add_node(FramebufferExtractLabel, FramebufferExtractNode);
- graph.add_node_edge(CameraDriverLabel, FramebufferExtractLabel);
+ let mut graph = render_app.world_mut().resource_mut::<RenderGraph>();
+ graph.add_node(HeadlessRenderCopyLabel, HeadlessRenderCopyNode);
+ graph.add_node_edge(CameraDriverLabel, HeadlessRenderCopyLabel);
}
}
diff --git a/src/nodes.rs b/src/nodes.rs
index 9791ad1..4e2ddd3 100644
--- a/src/nodes.rs
+++ b/src/nodes.rs
@@ -4,19 +4,19 @@ use bevy::{
render_asset::RenderAssets,
render_graph::{Node, NodeRunError, RenderGraphContext, RenderLabel},
render_resource::{ImageCopyBuffer, ImageDataLayout},
- renderer::RenderContext,
+ renderer::RenderContext, texture::GpuImage,
},
};
-use crate::render_assets::FramebufferExtractSource;
+use crate::render_assets::GpuHeadlessRenderSource;
#[derive(RenderLabel, Clone, PartialEq, Eq, Debug, Hash)]
-pub struct FramebufferExtractLabel;
+pub struct HeadlessRenderCopyLabel;
#[derive(Default)]
-pub struct FramebufferExtractNode;
+pub struct HeadlessRenderCopyNode;
-impl Node for FramebufferExtractNode {
+impl Node for HeadlessRenderCopyNode {
fn run(
&self,
_graph: &mut RenderGraphContext,
@@ -24,12 +24,12 @@ impl Node for FramebufferExtractNode {
world: &World,
) -> Result<(), NodeRunError> {
for (_, source) in world
- .resource::<RenderAssets<FramebufferExtractSource>>()
+ .resource::<RenderAssets<GpuHeadlessRenderSource>>()
.iter()
{
let Some(gpu_image) = world
- .resource::<RenderAssets<Image>>()
- .get(&source.source_handle)
+ .resource::<RenderAssets<GpuImage>>()
+ .get(source.source_handle.id())
else {
return Ok(());
};
diff --git a/src/render_assets.rs b/src/render_assets.rs
index e5277d7..48efdd0 100644
--- a/src/render_assets.rs
+++ b/src/render_assets.rs
@@ -2,14 +2,14 @@ use bevy::{
ecs::system::{lifetimeless::SRes, SystemParamItem},
prelude::*,
render::{
- render_asset::{PrepareAssetError, RenderAsset, RenderAssetUsages, RenderAssets},
+ render_asset::{PrepareAssetError, RenderAsset, RenderAssets},
render_resource::{Buffer, BufferDescriptor, BufferUsages, Extent3d, TextureFormat},
- renderer::RenderDevice,
+ renderer::RenderDevice, texture::GpuImage,
},
};
-/// Render-world version of FramebufferExtractSource
-pub struct GpuFramebufferExtractSource {
+/// Render-world version of HeadlessRenderSource
+pub struct GpuHeadlessRenderSource {
pub(crate) buffer: Buffer,
pub(crate) source_handle: Handle<Image>,
pub(crate) source_size: Extent3d,
@@ -18,26 +18,22 @@ pub struct GpuFramebufferExtractSource {
pub(crate) format: TextureFormat,
}
-/// Framebuffer extraction source. Contains a handle to the render texture which will be extracted
+/// Headless render source. Contains a handle to the render texture which will be copied
/// from.
#[derive(Asset, Reflect, Clone, Default)]
-pub struct FramebufferExtractSource(pub Handle<Image>);
+pub struct HeadlessRenderSource(pub Handle<Image>);
-impl RenderAsset for FramebufferExtractSource {
- type PreparedAsset = GpuFramebufferExtractSource;
- type Param = (SRes<RenderDevice>, SRes<RenderAssets<Image>>);
-
- fn asset_usage(&self) -> RenderAssetUsages {
- RenderAssetUsages::default()
- }
+impl RenderAsset for GpuHeadlessRenderSource {
+ type SourceAsset = HeadlessRenderSource;
+ type Param = (SRes<RenderDevice>, SRes<RenderAssets<GpuImage>>);
fn prepare_asset(
- self,
+ source_asset: Self::SourceAsset,
(device, images): &mut SystemParamItem<Self::Param>,
- ) -> Result<Self::PreparedAsset, PrepareAssetError<Self>> {
- let Some(gpu_image) = images.get(&self.0) else {
+ ) -> Result<Self, PrepareAssetError<Self::SourceAsset>> {
+ let Some(gpu_image) = images.get(source_asset.0.id()) else {
warn!("Failed to get GPU image");
- return Err(PrepareAssetError::RetryNextUpdate(self));
+ return Err(PrepareAssetError::RetryNextUpdate(source_asset));
};
let size = gpu_image.texture.size();
@@ -47,18 +43,19 @@ impl RenderAsset for FramebufferExtractSource {
let padded_bytes_per_row =
RenderDevice::align_copy_bytes_per_row(bytes_per_row as usize) as u32;
- Ok(GpuFramebufferExtractSource {
+ Ok(GpuHeadlessRenderSource {
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_handle: source_asset.0.clone(),
source_size: size,
bytes_per_row,
padded_bytes_per_row,
format,
})
}
+
}
diff --git a/src/systems.rs b/src/systems.rs
index 74f8dc8..bb0efc7 100644
--- a/src/systems.rs
+++ b/src/systems.rs
@@ -9,17 +9,17 @@ use bevy::{
use pollster::FutureExt;
-use crate::{components::FramebufferExtractDestination, render_assets::FramebufferExtractSource};
+use crate::{components::HeadlessRenderDestination, render_assets::{HeadlessRenderSource, GpuHeadlessRenderSource}};
-pub fn extract_framebuffers(
- mut extract_bundles: Query<(
- &Handle<FramebufferExtractSource>,
- &mut FramebufferExtractDestination,
+pub fn copy_buffers(
+ mut headless_render_query: Query<(
+ &Handle<HeadlessRenderSource>,
+ &mut HeadlessRenderDestination,
)>,
- sources: Res<RenderAssets<FramebufferExtractSource>>,
+ sources: Res<RenderAssets<GpuHeadlessRenderSource>>,
device: Res<RenderDevice>,
) {
- for (source_handle, destination_handle) in extract_bundles.iter_mut() {
+ for (source_handle, destination_handle) in headless_render_query.iter_mut() {
let Some(gpu_source) = sources.get(source_handle) else {
continue;
};