Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Headless renderer example has been added #13006

Merged

Conversation

bugsweeper
Copy link
Contributor

@bugsweeper bugsweeper commented Apr 17, 2024

Objective

Fixes #11457.
Fixes #22.

Solution

Based on another headless application


Changelog

  • Adopted to bevy 0.14

@bugsweeper
Copy link
Contributor Author

@alice-i-cecile May I ask you for a review?

@pablo-lua pablo-lua added A-Rendering Drawing game state to the screen C-Examples An addition or correction to our examples labels Apr 17, 2024
Copy link
Contributor

@IceSentry IceSentry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick review of the first couple of things I saw, this isn't a comprehensive review.

The code seems to do a lot of things and I'd prefer if it could be streamlined a bit to be easier to follow, but it's hard to know if there are parts of it that aren't as important because it lacks documentation of what all the pieces are.

examples/app/headless_renderer.rs Outdated Show resolved Hide resolved
examples/app/headless_renderer.rs Outdated Show resolved Hide resolved
examples/app/headless_renderer.rs Outdated Show resolved Hide resolved
examples/app/headless_renderer.rs Outdated Show resolved Hide resolved
examples/app/headless_renderer.rs Outdated Show resolved Hide resolved
examples/app/headless_renderer.rs Show resolved Hide resolved
@bugsweeper
Copy link
Contributor Author

@IceSentry , may I ask you for a rereview?

examples/app/headless_renderer.rs Outdated Show resolved Hide resolved
examples/app/headless_renderer.rs Show resolved Hide resolved
examples/app/headless_renderer.rs Outdated Show resolved Hide resolved
examples/app/headless_renderer.rs Outdated Show resolved Hide resolved
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
@mockersf
Copy link
Member

could you add objects to the scene, so that it doesn't render just a black picture?

the example panics for me:


Adding CaptureFramePlugin
Saving image to: "bevy/test_images"
thread 'Compute Task Pool (3)' panicked at examples/app/headless_renderer.rs:300:22:
Failed to send data to main world: "SendError(..)"
stack backtrace:
   0: rust_begin_unwind
             at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/std/src/panicking.rs:647:5
   1: core::panicking::panic_fmt
             at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/panicking.rs:72:14
   2: core::result::unwrap_failed
             at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/result.rs:1649:5
   3: core::result::Result<T,E>::expect
             at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/result.rs:1030:23
   4: headless_renderer::frame_capture::image_copy::receive_image_from_buffer
             at ./examples/app/headless_renderer.rs:298:17
   5: core::ops::function::FnMut::call_mut
             at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:166:5
   6: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/ops/function.rs:294:13
   7: <Func as bevy_ecs::system::function_system::SystemParamFunction<fn(F0,F1,F2) .> Out>>::run::call_inner
             at ./crates/bevy_ecs/src/system/function_system.rs:665:21
   8: <Func as bevy_ecs::system::function_system::SystemParamFunction<fn(F0,F1,F2) .> Out>>::run
             at ./crates/bevy_ecs/src/system/function_system.rs:668:17
   9: <bevy_ecs::system::function_system::FunctionSystem<Marker,F> as bevy_ecs::system::system::System>::run_unsafe
             at ./crates/bevy_ecs/src/system/function_system.rs:507:19
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Encountered a panic in system `headless_renderer::frame_capture::image_copy::receive_image_from_buffer`!

Is it possible to not surface that panic?

Comment on lines 489 to 490
let number = rng.gen::<u128>();
let image_path = images_dir.join(format!("{number:032X}.png"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use an incrementing number instead of a random value?

replace println to info

Co-authored-by: François Mockers <francois.mockers@vleue.com>
@bugsweeper
Copy link
Contributor Author

bugsweeper commented Apr 29, 2024

thread 'Compute Task Pool (3)' panicked at examples/app/headless_renderer.rs:300:22:
Failed to send data to main world: "SendError(..)"
Is it possible to not surface that panic?

The reason of this panic is attempt to send image data to nonexistent receiver, because MainWorld destroyed while RenderWorld still renders. For such case I left comment
// This could fail on app exit, if Main world clears resources while Render world still renders
Simple solution is ignoring Result of that send (there is .expect("...") now), more complex solution is to notify RenderWorld that an exit event has emitted, may be via some Atomic<bool>.

@bugsweeper
Copy link
Contributor Author

bugsweeper commented Apr 29, 2024

@mockersf May I ask you for a rereview?

@alice-i-cecile alice-i-cecile added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label May 5, 2024
Copy link
Contributor

@pcwalton pcwalton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine.

Copy link
Contributor

@tychedelia tychedelia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the comment about the nested modules being unnecessary for an example but otherwise lgtm.

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 5, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue May 5, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 5, 2024
Comment on lines 463 to 476
let mut cpu_image = Image {
texture_descriptor: TextureDescriptor {
label: None,
size,
dimension: TextureDimension::D2,
format: TextureFormat::Rgba8UnormSrgb,
mip_level_count: 1,
sample_count: 1,
usage: TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING,
view_formats: &[],
},
..Default::default()
};
cpu_image.resize(size);
Copy link
Contributor

@IceSentry IceSentry May 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified a little with this:

Suggested change
let mut cpu_image = Image {
texture_descriptor: TextureDescriptor {
label: None,
size,
dimension: TextureDimension::D2,
format: TextureFormat::Rgba8UnormSrgb,
mip_level_count: 1,
sample_count: 1,
usage: TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING,
view_formats: &[],
},
..Default::default()
};
cpu_image.resize(size);
let cpu_image = Image::new_fill(
size,
TextureDimension::D2,
&[0; 4],
TextureFormat::bevy_default(),
RenderAssetUsages::default(),
);

Comment on lines 443 to 459
let mut render_target_image = Image {
texture_descriptor: TextureDescriptor {
label: None,
size,
dimension: TextureDimension::D2,
format: TextureFormat::Rgba8UnormSrgb,
mip_level_count: 1,
sample_count: 1,
usage: TextureUsages::COPY_SRC
| TextureUsages::COPY_DST
| TextureUsages::TEXTURE_BINDING
| TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
},
..Default::default()
};
render_target_image.resize(size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let mut render_target_image = Image {
texture_descriptor: TextureDescriptor {
label: None,
size,
dimension: TextureDimension::D2,
format: TextureFormat::Rgba8UnormSrgb,
mip_level_count: 1,
sample_count: 1,
usage: TextureUsages::COPY_SRC
| TextureUsages::COPY_DST
| TextureUsages::TEXTURE_BINDING
| TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
},
..Default::default()
};
render_target_image.resize(size);
let mut render_target_image = Image::new_fill(
size,
TextureDimension::D2,
&[0; 4],
TextureFormat::bevy_default(),
RenderAssetUsages::default(),
);
render_target_image .texture_descriptor.usage |= TextureUsages::RENDER_ATTACHMENT | TextureUsages::TEXTURE_BINDING;

Copy link
Contributor

@IceSentry IceSentry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's a few things that can be improved to simplify this example a little, but it's probably better to merge it as-is and improve it later.

I haven't tested my suggestions, but I know they should roughly work. There might be some fmt issues.

@alice-i-cecile
Copy link
Member

@bugsweeper those suggestions look solid, but once CI is green I'll merge this in either way :)

Comment on lines 527 to 530
while image_path.exists() {
number += 1;
image_path = images_dir.join(format!("{number:03}.png"));
}
Copy link
Member

@mockersf mockersf May 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could keep a Local<u32> as a system parameter instead of iterating on every file. this has the potential to blow up

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example can be run multiple times with single_image option, Local helps only at first run with multiple files

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overwriting files from a previous run seems better to me than iterating over every files. additional bonus is that we create less random files on their computer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Searching free filenames has been changed to Local usage

Copy link
Member

@mockersf mockersf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interaction with the file system should be improved or commented

@mockersf mockersf removed the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label May 5, 2024
@bugsweeper bugsweeper requested a review from mockersf May 5, 2024 22:37
@bugsweeper bugsweeper force-pushed the add-headless-render-to-file branch from 08c6aff to b74e238 Compare May 5, 2024 22:45
@bugsweeper
Copy link
Contributor Author

@mockersf May I ask you for a rereview?

@mockersf mockersf added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label May 6, 2024
@bugsweeper
Copy link
Contributor Author

@alice-i-cecile Ci is green now

@alice-i-cecile alice-i-cecile added this pull request to the merge queue May 8, 2024
Merged via the queue into bevyengine:main with commit d9d305d May 8, 2024
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Examples An addition or correction to our examples D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it X-Uncontroversial This work is generally agreed upon
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a fully functional headless rendering example Headless rendering to images
8 participants