mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 12:43:34 +00:00
Sprite change image (#3207)
# Objective - Changing the underlying image would not update a sprite ## Solution - 'Detect' if the underlying image changes to update the sprite Currently, we don't support change detection on `RenderAssets`, so we have to manually check it. This method at least maintains the bind groups when the image isn't changing. They were cached, so I assume that's important. This gives us correct behaviour here. Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
parent
2def9027d7
commit
5fe73be2b5
3 changed files with 46 additions and 4 deletions
|
@ -102,9 +102,8 @@ fn extract_render_asset<A: RenderAsset>(
|
|||
changed_assets.insert(handle);
|
||||
}
|
||||
AssetEvent::Removed { handle } => {
|
||||
if !changed_assets.remove(handle) {
|
||||
removed.push(handle.clone_weak());
|
||||
}
|
||||
changed_assets.remove(handle);
|
||||
removed.push(handle.clone_weak());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,9 @@ impl Plugin for SpritePlugin {
|
|||
.init_resource::<SpecializedPipelines<SpritePipeline>>()
|
||||
.init_resource::<SpriteMeta>()
|
||||
.init_resource::<ExtractedSprites>()
|
||||
.init_resource::<SpriteAssetEvents>()
|
||||
.add_system_to_stage(RenderStage::Extract, render::extract_sprites)
|
||||
.add_system_to_stage(RenderStage::Extract, render::extract_sprite_events)
|
||||
.add_system_to_stage(RenderStage::Prepare, render::prepare_sprites)
|
||||
.add_system_to_stage(RenderStage::Queue, queue_sprites);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
|||
texture_atlas::{TextureAtlas, TextureAtlasSprite},
|
||||
Rect, Sprite, SPRITE_SHADER_HANDLE,
|
||||
};
|
||||
use bevy_asset::{Assets, Handle};
|
||||
use bevy_asset::{AssetEvent, Assets, Handle};
|
||||
use bevy_core::FloatOrd;
|
||||
use bevy_core_pipeline::Transparent2d;
|
||||
use bevy_ecs::{
|
||||
|
@ -172,6 +172,37 @@ pub struct ExtractedSprites {
|
|||
sprites: Vec<ExtractedSprite>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SpriteAssetEvents {
|
||||
images: Vec<AssetEvent<Image>>,
|
||||
}
|
||||
|
||||
pub fn extract_sprite_events(
|
||||
mut render_world: ResMut<RenderWorld>,
|
||||
mut image_events: EventReader<AssetEvent<Image>>,
|
||||
) {
|
||||
let mut events = render_world
|
||||
.get_resource_mut::<SpriteAssetEvents>()
|
||||
.unwrap();
|
||||
let SpriteAssetEvents { ref mut images } = *events;
|
||||
images.clear();
|
||||
|
||||
for image in image_events.iter() {
|
||||
// AssetEvent: !Clone
|
||||
images.push(match image {
|
||||
AssetEvent::Created { handle } => AssetEvent::Created {
|
||||
handle: handle.clone_weak(),
|
||||
},
|
||||
AssetEvent::Modified { handle } => AssetEvent::Modified {
|
||||
handle: handle.clone_weak(),
|
||||
},
|
||||
AssetEvent::Removed { handle } => AssetEvent::Removed {
|
||||
handle: handle.clone_weak(),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_sprites(
|
||||
mut render_world: ResMut<RenderWorld>,
|
||||
images: Res<Assets<Image>>,
|
||||
|
@ -453,7 +484,17 @@ pub fn queue_sprites(
|
|||
gpu_images: Res<RenderAssets<Image>>,
|
||||
mut sprite_batches: Query<(Entity, &SpriteBatch)>,
|
||||
mut views: Query<&mut RenderPhase<Transparent2d>>,
|
||||
events: Res<SpriteAssetEvents>,
|
||||
) {
|
||||
// If an image has changed, the GpuImage has (probably) changed
|
||||
for event in &events.images {
|
||||
match event {
|
||||
AssetEvent::Created { .. } => None,
|
||||
AssetEvent::Modified { handle } => image_bind_groups.values.remove(handle),
|
||||
AssetEvent::Removed { handle } => image_bind_groups.values.remove(handle),
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(view_binding) = view_uniforms.uniforms.binding() {
|
||||
sprite_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[BindGroupEntry {
|
||||
|
|
Loading…
Reference in a new issue