Merge branch 'imbris/screenshot-format' into 'master'

Support multiple texture formats for screenshots

See merge request veloren/veloren!3134
This commit is contained in:
Imbris 2022-01-25 14:45:54 +00:00
commit 432d78a232
3 changed files with 50 additions and 10 deletions

View File

@ -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<image::DynamicImage, String>) + Send + 'static,
) {
// Queue screenshot
self.take_screenshot = Some(Box::new(screenshot_handler));

View File

@ -1,7 +1,7 @@
use super::super::pipelines::blit;
use tracing::error;
pub type ScreenshotFn = Box<dyn FnOnce(image::DynamicImage) + Send>;
pub type ScreenshotFn = Box<dyn FnOnce(Result<image::DynamicImage, String>) + 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::<image::Bgra<u8>, Vec<u8>>::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::<image::Bgra<u8>, Vec<u8>>::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::<image::Rgba<u8>, Vec<u8>>::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);

View File

@ -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) {