1use crate::{Image, TextureFormatPixelInfo};
2use bevy_asset::RenderAssetUsages;
3use bevy_asset::{io::Reader, AssetLoader, LoadContext};
4use bevy_reflect::TypePath;
5use image::DynamicImage;
6use serde::{Deserialize, Serialize};
7use thiserror::Error;
8use wgpu_types::{Extent3d, TextureDimension, TextureFormat};
9
10#[derive(#[automatically_derived]
impl ::core::clone::Clone for HdrTextureLoader {
#[inline]
fn clone(&self) -> HdrTextureLoader { HdrTextureLoader }
}Clone, #[automatically_derived]
impl ::core::default::Default for HdrTextureLoader {
#[inline]
fn default() -> HdrTextureLoader { HdrTextureLoader {} }
}Default, const _: () =
{
#[allow(deprecated, reason =
"derives on a deprecated type shouldn't be considered a usage")]
impl bevy_reflect::TypePath for HdrTextureLoader where {
fn type_path() -> &'static str {
"bevy_image::hdr_texture_loader::HdrTextureLoader"
}
fn short_type_path() -> &'static str { "HdrTextureLoader" }
fn type_ident() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("HdrTextureLoader")
}
fn crate_name() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_image::hdr_texture_loader".split(':').next().unwrap())
}
fn module_path() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_image::hdr_texture_loader")
}
}
};TypePath)]
12pub struct HdrTextureLoader;
13
14#[derive(#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
{
#[allow(unused_extern_crates, clippy :: useless_attribute)]
extern crate serde as _serde;
;
#[automatically_derived]
impl _serde::Serialize for HdrTextureLoaderSettings {
fn serialize<__S>(&self, __serializer: __S)
-> _serde::__private228::Result<__S::Ok, __S::Error> where
__S: _serde::Serializer {
let mut __serde_state =
_serde::Serializer::serialize_struct(__serializer,
"HdrTextureLoaderSettings", false as usize + 1)?;
_serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
"asset_usage", &self.asset_usage)?;
_serde::ser::SerializeStruct::end(__serde_state)
}
}
};Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
{
#[allow(unused_extern_crates, clippy :: useless_attribute)]
extern crate serde as _serde;
;
#[automatically_derived]
impl<'de> _serde::Deserialize<'de> for HdrTextureLoaderSettings {
fn deserialize<__D>(__deserializer: __D)
-> _serde::__private228::Result<Self, __D::Error> where
__D: _serde::Deserializer<'de> {
#[allow(non_camel_case_types)]
#[doc(hidden)]
enum __Field { __field0, __ignore, }
#[doc(hidden)]
struct __FieldVisitor;
#[automatically_derived]
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(&self,
__formatter: &mut _serde::__private228::Formatter)
-> _serde::__private228::fmt::Result {
_serde::__private228::Formatter::write_str(__formatter,
"field identifier")
}
fn visit_u64<__E>(self, __value: u64)
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
0u64 => _serde::__private228::Ok(__Field::__field0),
_ => _serde::__private228::Ok(__Field::__ignore),
}
}
fn visit_str<__E>(self, __value: &str)
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
"asset_usage" =>
_serde::__private228::Ok(__Field::__field0),
_ => { _serde::__private228::Ok(__Field::__ignore) }
}
}
fn visit_bytes<__E>(self, __value: &[u8])
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
b"asset_usage" =>
_serde::__private228::Ok(__Field::__field0),
_ => { _serde::__private228::Ok(__Field::__ignore) }
}
}
}
#[automatically_derived]
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(__deserializer: __D)
-> _serde::__private228::Result<Self, __D::Error> where
__D: _serde::Deserializer<'de> {
_serde::Deserializer::deserialize_identifier(__deserializer,
__FieldVisitor)
}
}
#[doc(hidden)]
struct __Visitor<'de> {
marker: _serde::__private228::PhantomData<HdrTextureLoaderSettings>,
lifetime: _serde::__private228::PhantomData<&'de ()>,
}
#[automatically_derived]
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = HdrTextureLoaderSettings;
fn expecting(&self,
__formatter: &mut _serde::__private228::Formatter)
-> _serde::__private228::fmt::Result {
_serde::__private228::Formatter::write_str(__formatter,
"struct HdrTextureLoaderSettings")
}
#[inline]
fn visit_seq<__A>(self, mut __seq: __A)
-> _serde::__private228::Result<Self::Value, __A::Error>
where __A: _serde::de::SeqAccess<'de> {
let __field0 =
match _serde::de::SeqAccess::next_element::<RenderAssetUsages>(&mut __seq)?
{
_serde::__private228::Some(__value) => __value,
_serde::__private228::None =>
return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
&"struct HdrTextureLoaderSettings with 1 element")),
};
_serde::__private228::Ok(HdrTextureLoaderSettings {
asset_usage: __field0,
})
}
#[inline]
fn visit_map<__A>(self, mut __map: __A)
-> _serde::__private228::Result<Self::Value, __A::Error>
where __A: _serde::de::MapAccess<'de> {
let mut __field0:
_serde::__private228::Option<RenderAssetUsages> =
_serde::__private228::None;
while let _serde::__private228::Some(__key) =
_serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
match __key {
__Field::__field0 => {
if _serde::__private228::Option::is_some(&__field0) {
return _serde::__private228::Err(<__A::Error as
_serde::de::Error>::duplicate_field("asset_usage"));
}
__field0 =
_serde::__private228::Some(_serde::de::MapAccess::next_value::<RenderAssetUsages>(&mut __map)?);
}
_ => {
let _ =
_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
}
}
}
let __field0 =
match __field0 {
_serde::__private228::Some(__field0) => __field0,
_serde::__private228::None =>
_serde::__private228::de::missing_field("asset_usage")?,
};
_serde::__private228::Ok(HdrTextureLoaderSettings {
asset_usage: __field0,
})
}
}
#[doc(hidden)]
const FIELDS: &'static [&'static str] = &["asset_usage"];
_serde::Deserializer::deserialize_struct(__deserializer,
"HdrTextureLoaderSettings", FIELDS,
__Visitor {
marker: _serde::__private228::PhantomData::<HdrTextureLoaderSettings>,
lifetime: _serde::__private228::PhantomData,
})
}
}
};Deserialize, #[automatically_derived]
impl ::core::default::Default for HdrTextureLoaderSettings {
#[inline]
fn default() -> HdrTextureLoaderSettings {
HdrTextureLoaderSettings {
asset_usage: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::fmt::Debug for HdrTextureLoaderSettings {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"HdrTextureLoaderSettings", "asset_usage", &&self.asset_usage)
}
}Debug)]
16pub struct HdrTextureLoaderSettings {
17 pub asset_usage: RenderAssetUsages,
19}
20
21#[non_exhaustive]
23#[derive(#[automatically_derived]
impl ::core::fmt::Debug for HdrTextureLoaderError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
HdrTextureLoaderError::Io(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Io",
&__self_0),
HdrTextureLoaderError::Image(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Image",
&__self_0),
}
}
}Debug, fn from(source: image::ImageError) -> Self {
HdrTextureLoaderError::Image { 0: source }
}Error)]
24pub enum HdrTextureLoaderError {
25 #[error("Could load texture: {0}")]
27 Io(#[from] std::io::Error),
28 #[error("Could not extract image: {0}")]
30 Image(#[from] image::ImageError),
31}
32
33impl AssetLoader for HdrTextureLoader {
34 type Asset = Image;
35 type Settings = HdrTextureLoaderSettings;
36 type Error = HdrTextureLoaderError;
37 async fn load(
38 &self,
39 reader: &mut dyn Reader,
40 settings: &Self::Settings,
41 _load_context: &mut LoadContext<'_>,
42 ) -> Result<Image, Self::Error> {
43 let format = TextureFormat::Rgba32Float;
44 let pixel_size = format.pixel_size().unwrap();
46 if true {
{
match (&pixel_size, &(4 * 4)) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val,
::core::option::Option::Some(format_args!("Format should have 32bit x 4 size")));
}
}
}
};
};debug_assert_eq!(pixel_size, 4 * 4, "Format should have 32bit x 4 size");
47
48 let mut bytes = Vec::new();
49 reader.read_to_end(&mut bytes).await?;
50 let decoder = image::codecs::hdr::HdrDecoder::new(bytes.as_slice())?;
51 let info = decoder.metadata();
52 let dynamic_image = DynamicImage::from_decoder(decoder)?;
53 let image_buffer = dynamic_image
54 .as_rgb32f()
55 .expect("HDR Image format should be Rgb32F");
56 let mut rgba_data = Vec::with_capacity(image_buffer.pixels().len() * pixel_size);
57
58 for rgb in image_buffer.pixels() {
59 let alpha = 1.0f32;
60
61 rgba_data.extend_from_slice(&rgb.0[0].to_le_bytes());
62 rgba_data.extend_from_slice(&rgb.0[1].to_le_bytes());
63 rgba_data.extend_from_slice(&rgb.0[2].to_le_bytes());
64 rgba_data.extend_from_slice(&alpha.to_le_bytes());
65 }
66
67 Ok(Image::new(
68 Extent3d {
69 width: info.width,
70 height: info.height,
71 depth_or_array_layers: 1,
72 },
73 TextureDimension::D2,
74 rgba_data,
75 format,
76 settings.asset_usage,
77 ))
78 }
79
80 fn extensions(&self) -> &[&str] {
81 &["hdr"]
82 }
83}