Skip to content

Commit

Permalink
image derive attribute array_texture_layers
Browse files Browse the repository at this point in the history
  • Loading branch information
NiklasEi committed Jul 6, 2024
1 parent 30c37cb commit 28a54a6
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

- custom `on_unimplemented` diagnostics for the `AssetCollection` trait
- image derive attribute `array_texture_layers`

## v0.21.0 - 05.07.2024
- support for Bevy 0.14
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 14 additions & 1 deletion bevy_asset_loader/examples/image_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn main() {
.continue_to_state(MyStates::Next)
.load_collection::<ImageAssets>(),
)
.add_systems(OnEnter(MyStates::Next), draw)
.add_systems(OnEnter(MyStates::Next), (draw, assert))
.run();
}

Expand All @@ -24,6 +24,10 @@ struct ImageAssets {
#[asset(path = "images/pixel_tree.png")]
#[asset(image(sampler = nearest))]
tree_nearest: Handle<Image>,

#[asset(path = "images/array_texture.png")]
#[asset(image(array_texture_layers = 4))]
array_texture: Handle<Image>,
}

fn draw(mut commands: Commands, image_assets: Res<ImageAssets>) {
Expand All @@ -48,6 +52,15 @@ fn draw(mut commands: Commands, image_assets: Res<ImageAssets>) {
});
}

fn assert(images: Res<ImageAssets>, image_assets: Res<Assets<Image>>) {
let array_texture = image_assets.get(&images.array_texture).unwrap();
assert_eq!(
array_texture.texture_descriptor.array_layer_count(),
4,
"The image should have been reinterpreted as array texture with 4 layers"
);
}

#[derive(Clone, Eq, PartialEq, Debug, Hash, Default, States)]
enum MyStates {
#[default]
Expand Down
47 changes: 29 additions & 18 deletions bevy_asset_loader_derive/src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ impl TryFrom<String> for SamplerType {
pub(crate) struct ImageAssetField {
pub field_ident: Ident,
pub asset_path: String,
pub sampler: SamplerType,
pub sampler: Option<SamplerType>,
pub array_texture_layers: Option<u32>,
}

#[derive(PartialEq, Debug)]
Expand Down Expand Up @@ -122,14 +123,16 @@ impl AssetField {
AssetField::Image(image) => {
let field_ident = image.field_ident.clone();
let asset_path = image.asset_path.clone();
let layers = image.array_texture_layers.unwrap_or_default();
let sampler = match image.sampler {
SamplerType::Linear => quote!(ImageSampler::linear()),
SamplerType::Nearest => quote!(ImageSampler::nearest()),
Some(SamplerType::Linear) | None => quote!(ImageSampler::linear()),
Some(SamplerType::Nearest) => quote!(ImageSampler::nearest()),
};
let descriptor = match image.sampler {
SamplerType::Linear => quote!(ImageSamplerDescriptor::linear()),
SamplerType::Nearest => quote!(ImageSamplerDescriptor::nearest()),
Some(SamplerType::Linear) | None => quote!(ImageSamplerDescriptor::linear()),
Some(SamplerType::Nearest) => quote!(ImageSamplerDescriptor::nearest()),
};
let is_sampler_set = image.sampler.is_some();

quote!(#token_stream #field_ident : {
use bevy::render::texture::{ImageSampler, ImageSamplerDescriptor};
Expand All @@ -142,18 +145,24 @@ impl AssetField {
let mut handle = asset_server.load(#asset_path);
let mut image = images.get_mut(&handle).expect("Only asset collection fields holding an `Image` handle can be annotated with `image`");

let is_different_sampler = if let ImageSampler::Descriptor(descriptor) = &image.sampler {
!descriptor.as_wgpu().eq(&#descriptor.as_wgpu())
} else {
false
};
if (#layers > 0) {
image.reinterpret_stacked_2d_as_array(#layers);
}

if (#is_sampler_set) {
let is_different_sampler = if let ImageSampler::Descriptor(descriptor) = &image.sampler {
!descriptor.as_wgpu().eq(&#descriptor.as_wgpu())
} else {
false
};

if is_different_sampler {
let mut cloned_image = image.clone();
cloned_image.sampler = #sampler;
handle = images.add(cloned_image);
} else {
image.sampler = #sampler;
if is_different_sampler {
let mut cloned_image = image.clone();
cloned_image.sampler = #sampler;
handle = images.add(cloned_image);
} else {
image.sampler = #sampler;
}
}

handle
Expand Down Expand Up @@ -531,6 +540,7 @@ pub(crate) struct AssetBuilder {
pub offset_x: Option<u32>,
pub offset_y: Option<u32>,
pub sampler: Option<SamplerType>,
pub array_texture_layers: Option<u32>,
}

impl AssetBuilder {
Expand Down Expand Up @@ -655,11 +665,12 @@ impl AssetBuilder {
self.is_mapped.into(),
));
}
if self.sampler.is_some() {
if self.sampler.is_some() || self.array_texture_layers.is_some() {
return Ok(AssetField::Image(ImageAssetField {
field_ident: self.field_ident.unwrap(),
asset_path: self.asset_path.unwrap(),
sampler: self.sampler.unwrap(),
sampler: self.sampler,
array_texture_layers: self.array_texture_layers
}));
}
let asset = BasicAssetField {
Expand Down
16 changes: 16 additions & 0 deletions bevy_asset_loader_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ impl ImageAttribute {
pub const ATTRIBUTE_NAME: &'static str = "image";
#[allow(dead_code)]
pub const SAMPLER: &'static str = "sampler";
#[allow(dead_code)]
pub const LAYERS: &'static str = "array_texture_layers";
}

pub(crate) const COLLECTION_ATTRIBUTE: &str = "collection";
Expand Down Expand Up @@ -476,6 +478,20 @@ fn parse_field(field: &Field) -> Result<AssetField, Vec<ParseFieldError>> {
"path",
));
}
} else if path == ImageAttribute::LAYERS {
if let Expr::Lit(ExprLit {
lit: Lit::Int(layers),
..
}) = &named_value.value
{
builder.array_texture_layers =
Some(layers.base10_parse::<u32>().unwrap());
} else {
errors.push(ParseFieldError::WrongAttributeType(
named_value.into_token_stream(),
"u32",
));
}
}
}
_ => {
Expand Down

0 comments on commit 28a54a6

Please sign in to comment.