mirror of
https://github.com/bevyengine/bevy
synced 2025-01-13 13:49:10 +00:00
9db70da96f
Fixes https://github.com/bevyengine/bevy/issues/1207 # Objective Right now, it's impossible to capture a screenshot of the entire window without forking bevy. This is because - The swapchain texture never has the COPY_SRC usage - It can't be accessed without taking ownership of it - Taking ownership of it breaks *a lot* of stuff ## Solution - Introduce a dedicated api for taking a screenshot of a given bevy window, and guarantee this screenshot will always match up with what gets put on the screen. --- ## Changelog - Added the `ScreenshotManager` resource with two functions, `take_screenshot` and `save_screenshot_to_disk`
152 lines
3.5 KiB
Rust
152 lines
3.5 KiB
Rust
use crate::define_atomic_id;
|
|
use std::ops::Deref;
|
|
|
|
use crate::render_resource::resource_macros::*;
|
|
|
|
define_atomic_id!(TextureId);
|
|
render_resource_wrapper!(ErasedTexture, wgpu::Texture);
|
|
|
|
/// A GPU-accessible texture.
|
|
///
|
|
/// May be converted from and dereferences to a wgpu [`Texture`](wgpu::Texture).
|
|
/// Can be created via [`RenderDevice::create_texture`](crate::renderer::RenderDevice::create_texture).
|
|
#[derive(Clone, Debug)]
|
|
pub struct Texture {
|
|
id: TextureId,
|
|
value: ErasedTexture,
|
|
}
|
|
|
|
impl Texture {
|
|
/// Returns the [`TextureId`].
|
|
#[inline]
|
|
pub fn id(&self) -> TextureId {
|
|
self.id
|
|
}
|
|
|
|
/// Creates a view of this texture.
|
|
pub fn create_view(&self, desc: &wgpu::TextureViewDescriptor) -> TextureView {
|
|
TextureView::from(self.value.create_view(desc))
|
|
}
|
|
}
|
|
|
|
impl From<wgpu::Texture> for Texture {
|
|
fn from(value: wgpu::Texture) -> Self {
|
|
Texture {
|
|
id: TextureId::new(),
|
|
value: ErasedTexture::new(value),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Deref for Texture {
|
|
type Target = wgpu::Texture;
|
|
|
|
#[inline]
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.value
|
|
}
|
|
}
|
|
|
|
define_atomic_id!(TextureViewId);
|
|
render_resource_wrapper!(ErasedTextureView, wgpu::TextureView);
|
|
render_resource_wrapper!(ErasedSurfaceTexture, wgpu::SurfaceTexture);
|
|
|
|
/// Describes a [`Texture`] with its associated metadata required by a pipeline or [`BindGroup`](super::BindGroup).
|
|
#[derive(Clone, Debug)]
|
|
pub struct TextureView {
|
|
id: TextureViewId,
|
|
value: ErasedTextureView,
|
|
}
|
|
|
|
pub struct SurfaceTexture {
|
|
value: ErasedSurfaceTexture,
|
|
}
|
|
|
|
impl SurfaceTexture {
|
|
pub fn try_unwrap(self) -> Option<wgpu::SurfaceTexture> {
|
|
self.value.try_unwrap()
|
|
}
|
|
}
|
|
|
|
impl TextureView {
|
|
/// Returns the [`TextureViewId`].
|
|
#[inline]
|
|
pub fn id(&self) -> TextureViewId {
|
|
self.id
|
|
}
|
|
}
|
|
|
|
impl From<wgpu::TextureView> for TextureView {
|
|
fn from(value: wgpu::TextureView) -> Self {
|
|
TextureView {
|
|
id: TextureViewId::new(),
|
|
value: ErasedTextureView::new(value),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<wgpu::SurfaceTexture> for SurfaceTexture {
|
|
fn from(value: wgpu::SurfaceTexture) -> Self {
|
|
SurfaceTexture {
|
|
value: ErasedSurfaceTexture::new(value),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Deref for TextureView {
|
|
type Target = wgpu::TextureView;
|
|
|
|
#[inline]
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.value
|
|
}
|
|
}
|
|
|
|
impl Deref for SurfaceTexture {
|
|
type Target = wgpu::SurfaceTexture;
|
|
|
|
#[inline]
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.value
|
|
}
|
|
}
|
|
|
|
define_atomic_id!(SamplerId);
|
|
render_resource_wrapper!(ErasedSampler, wgpu::Sampler);
|
|
|
|
/// A Sampler defines how a pipeline will sample from a [`TextureView`].
|
|
/// They define image filters (including anisotropy) and address (wrapping) modes, among other things.
|
|
///
|
|
/// May be converted from and dereferences to a wgpu [`Sampler`](wgpu::Sampler).
|
|
/// Can be created via [`RenderDevice::create_sampler`](crate::renderer::RenderDevice::create_sampler).
|
|
#[derive(Clone, Debug)]
|
|
pub struct Sampler {
|
|
id: SamplerId,
|
|
value: ErasedSampler,
|
|
}
|
|
|
|
impl Sampler {
|
|
/// Returns the [`SamplerId`].
|
|
#[inline]
|
|
pub fn id(&self) -> SamplerId {
|
|
self.id
|
|
}
|
|
}
|
|
|
|
impl From<wgpu::Sampler> for Sampler {
|
|
fn from(value: wgpu::Sampler) -> Self {
|
|
Sampler {
|
|
id: SamplerId::new(),
|
|
value: ErasedSampler::new(value),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Deref for Sampler {
|
|
type Target = wgpu::Sampler;
|
|
|
|
#[inline]
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.value
|
|
}
|
|
}
|