mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 20:53:53 +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);
|
changed_assets.insert(handle);
|
||||||
}
|
}
|
||||||
AssetEvent::Removed { handle } => {
|
AssetEvent::Removed { handle } => {
|
||||||
if !changed_assets.remove(handle) {
|
changed_assets.remove(handle);
|
||||||
removed.push(handle.clone_weak());
|
removed.push(handle.clone_weak());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,9 @@ impl Plugin for SpritePlugin {
|
||||||
.init_resource::<SpecializedPipelines<SpritePipeline>>()
|
.init_resource::<SpecializedPipelines<SpritePipeline>>()
|
||||||
.init_resource::<SpriteMeta>()
|
.init_resource::<SpriteMeta>()
|
||||||
.init_resource::<ExtractedSprites>()
|
.init_resource::<ExtractedSprites>()
|
||||||
|
.init_resource::<SpriteAssetEvents>()
|
||||||
.add_system_to_stage(RenderStage::Extract, render::extract_sprites)
|
.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::Prepare, render::prepare_sprites)
|
||||||
.add_system_to_stage(RenderStage::Queue, queue_sprites);
|
.add_system_to_stage(RenderStage::Queue, queue_sprites);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
texture_atlas::{TextureAtlas, TextureAtlasSprite},
|
texture_atlas::{TextureAtlas, TextureAtlasSprite},
|
||||||
Rect, Sprite, SPRITE_SHADER_HANDLE,
|
Rect, Sprite, SPRITE_SHADER_HANDLE,
|
||||||
};
|
};
|
||||||
use bevy_asset::{Assets, Handle};
|
use bevy_asset::{AssetEvent, Assets, Handle};
|
||||||
use bevy_core::FloatOrd;
|
use bevy_core::FloatOrd;
|
||||||
use bevy_core_pipeline::Transparent2d;
|
use bevy_core_pipeline::Transparent2d;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
|
@ -172,6 +172,37 @@ pub struct ExtractedSprites {
|
||||||
sprites: Vec<ExtractedSprite>,
|
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(
|
pub fn extract_sprites(
|
||||||
mut render_world: ResMut<RenderWorld>,
|
mut render_world: ResMut<RenderWorld>,
|
||||||
images: Res<Assets<Image>>,
|
images: Res<Assets<Image>>,
|
||||||
|
@ -453,7 +484,17 @@ pub fn queue_sprites(
|
||||||
gpu_images: Res<RenderAssets<Image>>,
|
gpu_images: Res<RenderAssets<Image>>,
|
||||||
mut sprite_batches: Query<(Entity, &SpriteBatch)>,
|
mut sprite_batches: Query<(Entity, &SpriteBatch)>,
|
||||||
mut views: Query<&mut RenderPhase<Transparent2d>>,
|
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() {
|
if let Some(view_binding) = view_uniforms.uniforms.binding() {
|
||||||
sprite_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor {
|
sprite_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor {
|
||||||
entries: &[BindGroupEntry {
|
entries: &[BindGroupEntry {
|
||||||
|
|
Loading…
Reference in a new issue