Skip to content

Commit

Permalink
Merge branch 'main' of github.com:NiklasEi/bevy_asset_loader into bev…
Browse files Browse the repository at this point in the history
…y_main
  • Loading branch information
NiklasEi committed Nov 1, 2023
2 parents a12fa08 + 412b9a9 commit a69394d
Show file tree
Hide file tree
Showing 13 changed files with 432 additions and 37 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-build-stable-${{ hashFiles('**/Cargo.toml') }}
key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.toml') }}
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
Expand All @@ -46,7 +46,7 @@ jobs:
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-build-stable-${{ hashFiles('**/Cargo.toml') }}
key: ${{ runner.os }}-cargo-test-2d-3d-dynamic-${{ hashFiles('**/Cargo.toml') }}
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
Expand All @@ -72,7 +72,7 @@ jobs:
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-build-stable-${{ hashFiles('**/Cargo.toml') }}
key: ${{ runner.os }}-cargo-progress-tracking-test-${{ hashFiles('**/Cargo.toml') }}
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
Expand All @@ -95,7 +95,7 @@ jobs:
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ubuntu-latest-cargo-build-stable-${{ hashFiles('**/Cargo.toml') }}
key: ubuntu-latest-cargo-lint-${{ hashFiles('**/Cargo.toml') }}
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog

- Make `loading_state::LoadingStateSet` public for explicit system ordering
- Support configuring an image sampler through a derive attribute ([#156](https://github.com/NiklasEi/bevy_asset_loader/pull/156))
- See [the new example](bevy_asset_loader/examples/image_asset.rs)
- This can is also supported in dynamic assets through the new standard dynamic asset `Image`
- Optional fields of dynamic assets no longer require wrapping their values in `Some`
- E.g. configuring `padding_x` for a texture atlas is now just `padding_x: 1.5` instead of `padding_x: Some(1.5)`

## v0.17.0
- update to Bevy 0.11
Expand Down
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,36 @@ struct MyAssets {
}
```

### Images

Asset collections support configuring the sampler of an image asset through a derive attribute. You can configure either the sampler like so:

```rust
use bevy::prelude::*;
use bevy_asset_loader::asset_collection::AssetCollection;

#[derive(AssetCollection, Resource)]
struct ImageAssets {
#[asset(path = "images/pixel_tree.png")]
#[asset(image(sampler = linear))]
tree_linear: Handle<Image>,

#[asset(path = "images/pixel_tree.png")]
#[asset(image(sampler = nearest))]
tree_nearest: Handle<Image>,
}
```

The corresponding dynamic asset would be
```ron
({
"pixel_tree": Image (
path: "images/tree.png",
sampler: Nearest
),
})
```

### Standard materials

You can directly load standard materials if you enable the feature `3d`. For a complete example please take a look at [standard_material.rs](bevy_asset_loader/examples/standard_material.rs).
Expand Down
5 changes: 5 additions & 0 deletions bevy_asset_loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,8 @@ required-features = ["2d", "3d", "standard_dynamic_assets"]
[[example]]
name = "custom_dynamic_assets"
path = "examples/custom_dynamic_assets.rs"

[[example]]
name = "image_asset"
path = "examples/image_asset.rs"
required-features = ["2d"]
6 changes: 5 additions & 1 deletion bevy_asset_loader/assets/full_dynamic_collection.assets.ron
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
tile_size_x: 96.,
tile_size_y: 99.,
columns: 8,
rows: 1
rows: 1,
),
"pixel_tree": Image (
path: "images/tree.png",
sampler: Nearest
),
"folder_untyped": Folder (
path: "images",
Expand Down
Binary file added bevy_asset_loader/assets/images/pixel_tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions bevy_asset_loader/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ with `cargo run --example <example>`.
| [`progress_tracking.rs`](progress_tracking.rs) | How to set up progress tracking using `iyes_progress` |
| [`standard_material.rs`](standard_material.rs) | Loading a standard material from a png file |
| [`two_collections.rs`](two_collections.rs) | Load multiple asset collections |
| [`image_asset.rs`](image_asset.rs) | How to set different samplers for image assets |

## Credits

Expand All @@ -27,3 +28,6 @@ by [Jay_You](https://freesound.org/people/Jay_You/sounds/460432/)

Toon character sheets [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/)
by [Kenny](https://kenney.nl/assets/toon-characters-1)

Pixelart tree [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/)
by [Kenny](https://www.kenney.nl/assets/tiny-town)
27 changes: 23 additions & 4 deletions bevy_asset_loader/examples/full_collection.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use bevy::app::AppExit;
use bevy::asset::RecursiveDependencyLoadState;
use bevy::prelude::*;
use bevy::render::texture::{ImageSampler, ImageSamplerDescriptor};
use bevy::utils::HashMap;
use bevy_asset_loader::prelude::*;

Expand Down Expand Up @@ -32,6 +33,11 @@ struct MyAssets {
// If no derive attributes are set, `from_world` will be used to set the value.
from_world: ColorStandardMaterial<{ u8::MAX }, 0, 0, { u8::MAX }>,

// Image asset with sampler nearest (good for crisp pixel art)
#[asset(path = "images/pixel_tree.png")]
#[asset(image(sampler = nearest))]
image_tree_nearest: Handle<Image>,

// Load collections of assets

// A folder (not supported on the web)
Expand Down Expand Up @@ -68,6 +74,7 @@ fn expectations(
asset_server: Res<AssetServer>,
standard_materials: Res<Assets<StandardMaterial>>,
texture_atlases: Res<Assets<TextureAtlas>>,
images: Res<Assets<Image>>,
mut quit: EventWriter<AppExit>,
) {
info!("Done loading the collection. Checking expectations...");
Expand Down Expand Up @@ -99,29 +106,41 @@ fn expectations(
.get(&assets.from_world.handle)
.expect("Standard material should be added to its assets resource.");
assert_eq!(material.base_color, Color::RED);
assert_eq!(assets.folder_untyped.len(), 6);

let image = images
.get(&assets.image_tree_nearest)
.expect("Image should be added to its asset resource");
let ImageSampler::Descriptor(descriptor) = &image.sampler else {
panic!("Descriptor was not set to non default value nearest");
};
assert_eq!(
descriptor.as_wgpu(),
ImageSamplerDescriptor::nearest().as_wgpu()
);

assert_eq!(assets.folder_untyped.len(), 7);
for handle in assets.folder_untyped.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Some(RecursiveDependencyLoadState::Loaded)
);
}
assert_eq!(assets.folder_typed.len(), 6);
assert_eq!(assets.folder_typed.len(), 7);
for handle in assets.folder_typed.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Some(RecursiveDependencyLoadState::Loaded)
);
}
assert_eq!(assets.mapped_folder_untyped.len(), 6);
assert_eq!(assets.mapped_folder_untyped.len(), 7);
for (name, handle) in assets.mapped_folder_untyped.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Some(RecursiveDependencyLoadState::Loaded)
);
assert_eq!(&handle.path().unwrap().to_string(), name);
}
assert_eq!(assets.mapped_folder_typed.len(), 6);
assert_eq!(assets.mapped_folder_typed.len(), 7);
for (name, handle) in assets.mapped_folder_typed.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Expand Down
32 changes: 24 additions & 8 deletions bevy_asset_loader/examples/full_dynamic_collection.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use bevy::app::AppExit;
use bevy::asset::RecursiveDependencyLoadState;
use bevy::prelude::*;
use bevy::render::texture::{ImageSampler, ImageSamplerDescriptor};
use bevy::utils::HashMap;
use bevy_asset_loader::prelude::*;

Expand Down Expand Up @@ -49,6 +50,9 @@ struct MyAssets {
// Type in `assets/full_dynamic_collection.assets.ron`: `File`, `StandardMaterial`, or `TextureAtlas`
#[asset(key = "optional_file", optional)]
optional_file: Option<Handle<AudioSource>>,
// Image asset with sampler nearest (good for crisp pixel art)
#[asset(key = "pixel_tree")]
image_tree_nearest: Handle<Image>,

// Collections of files

Expand Down Expand Up @@ -106,6 +110,7 @@ fn expectations(
asset_server: Res<AssetServer>,
standard_materials: Res<Assets<StandardMaterial>>,
texture_atlases: Res<Assets<TextureAtlas>>,
images: Res<Assets<Image>>,
mut quit: EventWriter<AppExit>,
) {
info!("Done loading the collection. Checking expectations...");
Expand Down Expand Up @@ -134,29 +139,40 @@ fn expectations(
Some(RecursiveDependencyLoadState::Loaded)
);
assert_eq!(assets.optional_file, None);
assert_eq!(assets.folder_untyped.len(), 6);
let image = images
.get(&assets.image_tree_nearest)
.expect("Image should be added to its asset resource");
let ImageSampler::Descriptor(descriptor) = &image.sampler else {
panic!("Descriptor was not set to non default value nearest");
};
assert_eq!(
descriptor.as_wgpu(),
ImageSamplerDescriptor::nearest().as_wgpu()
);

assert_eq!(assets.folder_untyped.len(), 7);
for handle in assets.folder_untyped.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Some(RecursiveDependencyLoadState::Loaded)
);
}
assert_eq!(assets.folder_untyped_mapped.len(), 6);
assert_eq!(assets.folder_untyped_mapped.len(), 7);
for (name, handle) in assets.folder_untyped_mapped.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Some(RecursiveDependencyLoadState::Loaded)
);
assert_eq!(&handle.path().unwrap().to_string(), name);
}
assert_eq!(assets.folder_typed.len(), 6);
assert_eq!(assets.folder_typed.len(), 7);
for handle in assets.folder_typed.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Some(RecursiveDependencyLoadState::Loaded)
);
}
assert_eq!(assets.folder_typed_mapped.len(), 6);
assert_eq!(assets.folder_typed_mapped.len(), 7);
for (name, handle) in assets.folder_typed_mapped.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Expand Down Expand Up @@ -199,7 +215,7 @@ fn expectations(
let Some(ref optional_folder_untyped) = assets.optional_folder_untyped else {
panic!("Optional asset not loaded")
};
assert_eq!(optional_folder_untyped.len(), 6);
assert_eq!(optional_folder_untyped.len(), 7);
for handle in optional_folder_untyped.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Expand All @@ -209,7 +225,7 @@ fn expectations(
let Some(ref optional_folder_untyped_mapped) = assets.optional_folder_untyped_mapped else {
panic!("Optional asset not loaded")
};
assert_eq!(optional_folder_untyped_mapped.len(), 6);
assert_eq!(optional_folder_untyped_mapped.len(), 7);
for (name, handle) in optional_folder_untyped_mapped.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Expand All @@ -220,7 +236,7 @@ fn expectations(
let Some(ref optional_folder_typed) = assets.optional_folder_typed else {
panic!("Optional asset not loaded")
};
assert_eq!(optional_folder_typed.len(), 6);
assert_eq!(optional_folder_typed.len(), 7);
for handle in optional_folder_typed.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Expand All @@ -230,7 +246,7 @@ fn expectations(
let Some(ref optional_folder_typed_mapped) = assets.optional_folder_typed_mapped else {
panic!("Optional asset not loaded")
};
assert_eq!(optional_folder_typed_mapped.len(), 6);
assert_eq!(optional_folder_typed_mapped.len(), 7);
for (name, handle) in optional_folder_typed_mapped.iter() {
assert_eq!(
asset_server.get_recursive_dependency_load_state(handle.id()),
Expand Down
56 changes: 56 additions & 0 deletions bevy_asset_loader/examples/image_asset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use bevy::prelude::*;
use bevy_asset_loader::prelude::*;

/// This example demonstrates how you can set a different sampler for an [`Image`].
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_state::<MyStates>()
.add_loading_state(
LoadingState::new(MyStates::AssetLoading).continue_to_state(MyStates::Next),
)
.add_collection_to_loading_state::<_, ImageAssets>(MyStates::AssetLoading)
.insert_resource(Msaa::Off)
.add_systems(OnEnter(MyStates::Next), draw)
.run();
}

#[derive(AssetCollection, Resource)]
struct ImageAssets {
#[asset(path = "images/pixel_tree.png")]
#[asset(image(sampler = linear))]
tree_linear: Handle<Image>,

#[asset(path = "images/pixel_tree.png")]
#[asset(image(sampler = nearest))]
tree_nearest: Handle<Image>,
}

fn draw(mut commands: Commands, image_assets: Res<ImageAssets>) {
commands.spawn(Camera2dBundle {
projection: OrthographicProjection {
far: 1000.,
near: -1000.,
scale: 0.25,
..default()
},
..default()
});
commands.spawn(SpriteBundle {
texture: image_assets.tree_linear.clone(),
transform: Transform::from_translation(Vec3::new(-50., 0., 1.)),
..Default::default()
});
commands.spawn(SpriteBundle {
texture: image_assets.tree_nearest.clone(),
transform: Transform::from_translation(Vec3::new(50., 0., 1.)),
..Default::default()
});
}

#[derive(Clone, Eq, PartialEq, Debug, Hash, Default, States)]
enum MyStates {
#[default]
AssetLoading,
Next,
}
Loading

0 comments on commit a69394d

Please sign in to comment.