diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index 62b929d6b5..719ac4a5f4 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -1342,7 +1342,7 @@ impl Renderer { /// Queue to obtain a screenshot on the next frame render pub fn create_screenshot( &mut self, - screenshot_handler: impl FnOnce(image::DynamicImage) + Send + 'static, + screenshot_handler: impl FnOnce(Result) + Send + 'static, ) { // Queue screenshot self.take_screenshot = Some(Box::new(screenshot_handler)); diff --git a/voxygen/src/render/renderer/screenshot.rs b/voxygen/src/render/renderer/screenshot.rs index 484b83ef4d..f8460cf9f9 100644 --- a/voxygen/src/render/renderer/screenshot.rs +++ b/voxygen/src/render/renderer/screenshot.rs @@ -1,7 +1,7 @@ use super::super::pipelines::blit; use tracing::error; -pub type ScreenshotFn = Box; +pub type ScreenshotFn = Box) + Send>; pub struct TakeScreenshot { bind_group: blit::BindGroup, @@ -13,6 +13,8 @@ pub struct TakeScreenshot { width: u32, height: u32, bytes_per_pixel: u8, + // Texture format + tex_format: wgpu::TextureFormat, } impl TakeScreenshot { @@ -74,6 +76,7 @@ impl TakeScreenshot { width: sc_desc.width, height: sc_desc.height, bytes_per_pixel, + tex_format: sc_desc.format, } } @@ -162,14 +165,40 @@ impl TakeScreenshot { }; // Construct image - // TODO: support other formats - let image = image::ImageBuffer::, Vec>::from_vec( - self.width, - self.height, - pixel_bytes, - ) - .expect("Failed to create ImageBuffer! Buffer was not large enough. This should not occur"); - let image = image::DynamicImage::ImageBgra8(image); + let image = match self.tex_format { + wgpu::TextureFormat::Bgra8UnormSrgb => { + let image = image::ImageBuffer::, Vec>::from_vec( + self.width, + self.height, + pixel_bytes, + ) + .expect( + "Failed to create ImageBuffer! Buffer was not large enough. This should not \ + occur", + ); + let image = image::DynamicImage::ImageBgra8(image); + + Ok(image) + }, + wgpu::TextureFormat::Rgba8UnormSrgb => { + let image = image::ImageBuffer::, Vec>::from_vec( + self.width, + self.height, + pixel_bytes, + ) + .expect( + "Failed to create ImageBuffer! Buffer was not large enough. This should not \ + occur", + ); + let image = image::DynamicImage::ImageRgba8(image); + + Ok(image) + }, + format => Err(format!( + "Unhandled format for screenshot texture: {:?}", + format, + )), + }; // Call supplied handler (self.screenshot_fn)(image); diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index 661edc1a7e..5275117f31 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -1262,6 +1262,17 @@ impl Window { let mut path = settings.screenshots_path.clone(); self.renderer.create_screenshot(move |image| { use std::time::SystemTime; + + // Handle any error if there was one when generating the image. + let image = match image { + Ok(i) => i, + Err(e) => { + warn!(?e, "Couldn't generate screenshot"); + let _result = sender.send(format!("Error when generating screenshot: {}", e)); + return; + }, + }; + // Check if folder exists and create it if it does not if !path.exists() { if let Err(e) = std::fs::create_dir_all(&path) {