bevy/examples/window
charlotte d9527c101c
Rewrite screenshots. (#14833)
# Objective

Rewrite screenshotting to be able to accept any `RenderTarget`.

Closes #12478 

## Solution

Previously, screenshotting relied on setting a variety of state on the
requested window. When extracted, the window's `swap_chain_texture_view`
property would be swapped out with a texture_view created that frame for
the screenshot pipeline to write back to the cpu.

Besides being tightly coupled to window in a way that prevented
screenshotting other render targets, this approach had the drawback of
relying on the implicit state of `swap_chain_texture_view` being
returned from a `NormalizedRenderTarget` when view targets were
prepared. Because property is set every frame for windows, that wasn't a
problem, but poses a problem for render target images. Namely, to do the
equivalent trick, we'd have to replace the `GpuImage`'s texture view,
and somehow restore it later.

As such, this PR creates a new `prepare_view_textures` system which runs
before `prepare_view_targets` that allows a new `prepare_screenshots`
system to be sandwiched between and overwrite the render targets texture
view if a screenshot has been requested that frame for the given target.

Additionally, screenshotting itself has been changed to use a component
+ observer pattern. We now spawn a `Screenshot` component into the
world, whose lifetime is tracked with a series of marker components.
When the screenshot is read back to the CPU, we send the image over a
channel back to the main world where an observer fires on the screenshot
entity before being despawned the next frame. This allows the user to
access resources in their save callback that might be useful (e.g.
uploading the screenshot over the network, etc.).

## Testing


![image](https://github.com/user-attachments/assets/48f19aed-d9e1-4058-bb17-82b37f992b7b)


TODO:
- [x] Web
- [ ] Manual texture view

---

## Showcase

render to texture example:
<img
src="https://github.com/user-attachments/assets/612ac47b-8a24-4287-a745-3051837963b0"
width=200/>

web saving still works:
<img
src="https://github.com/user-attachments/assets/e2a15b17-1ff5-4006-ab2a-e5cc74888b9c"
width=200/>

## Migration Guide

`ScreenshotManager` has been removed. To take a screenshot, spawn a
`Screenshot` entity with the specified render target and provide an
observer targeting the `ScreenshotCaptured` event. See the
`window/screenshot` example to see an example.

---------

Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
2024-08-25 14:14:32 +00:00
..
clear_color.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
custom_user_event.rs Remove need for EventLoopProxy to be NonSend (#14198) 2024-07-16 06:59:01 +00:00
low_power.rs Remove need for EventLoopProxy to be NonSend (#14198) 2024-07-16 06:59:01 +00:00
monitor_info.rs Expose winit's MonitorHandle (#13669) 2024-08-06 10:54:37 +00:00
multiple_windows.rs glTF labels: add enum to avoid misspelling and keep up-to-date list documented (#13586) 2024-05-31 23:25:57 +00:00
scale_factor_override.rs fix: upgrade to winit v0.30 (#13366) 2024-06-03 13:06:48 +00:00
screenshot.rs Rewrite screenshots. (#14833) 2024-08-25 14:14:32 +00:00
transparent_window.rs Remove redundant imports (#12817) 2024-04-01 19:59:08 +00:00
window_resizing.rs Made the naming for commands parameter more consistent (#14851) 2024-08-22 16:53:05 +00:00
window_settings.rs Add custom cursors (#14284) 2024-08-12 15:49:03 +00:00