Skip to content

Commit e24ae6c

Browse files
authored
Move TextureAtlas and friends into bevy_image (#17219)
# Objective - Allow other crates to use `TextureAtlas` and friends without needing to depend on `bevy_sprite`. - Specifically, this allows adding `TextureAtlas` support to custom cursors in #17121 by allowing `bevy_winit` to depend on `bevy_image` instead of `bevy_sprite` which is a [non-starter]. [non-starter]: #17121 (comment) ## Solution - Move `TextureAtlas`, `TextureAtlasBuilder`, `TextureAtlasSources`, `TextureAtlasLayout` and `DynamicTextureAtlasBuilder` into `bevy_image`. - Add a new plugin to `bevy_image` named `TextureAtlasPlugin` which allows us to register `TextureAtlas` and `TextureAtlasLayout` which was previously done in `SpritePlugin`. Since `SpritePlugin` did the registration previously, we just need to make it add `TextureAtlasPlugin`. ## Testing - CI builds it. - I also ran multiple examples which hopefully covered any issues: ``` $ cargo run --example sprite $ cargo run --example text $ cargo run --example ui_texture_atlas $ cargo run --example sprite_animation $ cargo run --example sprite_sheet $ cargo run --example sprite_picking ``` --- ## Migration Guide The following types have been moved from `bevy_sprite` to `bevy_image`: `TextureAtlas`, `TextureAtlasBuilder`, `TextureAtlasSources`, `TextureAtlasLayout` and `DynamicTextureAtlasBuilder`. If you are using the `bevy` crate, and were importing these types directly (e.g. before `use bevy::sprite::TextureAtlas`), be sure to update your import paths (e.g. after `use bevy::image::TextureAtlas`) If you are using the `bevy` prelude to import these types (e.g. `use bevy::prelude::*`), you don't need to change anything. If you are using the `bevy_sprite` subcrate, be sure to add `bevy_image` as a dependency if you do not already have it, and be sure to update your import paths.
1 parent 3578f9e commit e24ae6c

20 files changed

+74
-64
lines changed

crates/bevy_image/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,15 @@ qoi = ["image/qoi"]
2626
tga = ["image/tga"]
2727
tiff = ["image/tiff"]
2828
webp = ["image/webp"]
29+
serialize = []
2930

3031
# For ktx2 supercompression
3132
zlib = ["flate2"]
3233
zstd = ["ruzstd"]
3334

3435
[dependencies]
36+
# bevy
37+
bevy_app = { path = "../bevy_app", version = "0.16.0-dev" }
3538
bevy_asset = { path = "../bevy_asset", version = "0.16.0-dev" }
3639
bevy_color = { path = "../bevy_color", version = "0.16.0-dev", features = [
3740
"serialize",
@@ -55,6 +58,8 @@ wgpu = { version = "23.0.1", default-features = false }
5558
serde = { version = "1", features = ["derive"] }
5659
thiserror = { version = "2", default-features = false }
5760
futures-lite = "2.0.1"
61+
guillotiere = "0.6.0"
62+
rectangle-pack = "0.4"
5863
ddsfile = { version = "0.5.2", optional = true }
5964
ktx2 = { version = "0.3.0", optional = true }
6065
# For ktx2 supercompression
@@ -64,6 +69,10 @@ ruzstd = { version = "0.7.0", optional = true }
6469
basis-universal = { version = "0.3.0", optional = true }
6570
tracing = { version = "0.1", default-features = false, features = ["std"] }
6671

72+
[dev-dependencies]
73+
bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
74+
bevy_sprite = { path = "../bevy_sprite", version = "0.16.0-dev" }
75+
6776
[lints]
6877
workspace = true
6978

crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs renamed to crates/bevy_image/src/dynamic_texture_atlas_builder.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use crate::TextureAtlasLayout;
2-
use bevy_image::{Image, TextureFormatPixelInfo};
1+
use crate::{Image, TextureAtlasLayout, TextureFormatPixelInfo as _};
2+
use bevy_asset::RenderAssetUsages;
33
use bevy_math::{URect, UVec2};
4-
use bevy_render::render_asset::RenderAssetUsages;
54
use guillotiere::{size2, Allocation, AtlasAllocator};
65

76
/// Helper utility to update [`TextureAtlasLayout`] on the fly.

crates/bevy_image/src/lib.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
#![expect(missing_docs, reason = "Not all docs are written yet, see #3492.")]
22
#![allow(unsafe_code)]
33

4+
extern crate alloc;
5+
46
pub mod prelude {
5-
pub use crate::{BevyDefault as _, Image, ImageFormat, TextureError};
7+
pub use crate::{
8+
dynamic_texture_atlas_builder::DynamicTextureAtlasBuilder,
9+
texture_atlas::{TextureAtlas, TextureAtlasLayout, TextureAtlasSources},
10+
BevyDefault as _, Image, ImageFormat, TextureAtlasBuilder, TextureError,
11+
};
612
}
713

814
mod image;
@@ -13,25 +19,31 @@ mod basis;
1319
mod compressed_image_saver;
1420
#[cfg(feature = "dds")]
1521
mod dds;
22+
mod dynamic_texture_atlas_builder;
1623
#[cfg(feature = "exr")]
1724
mod exr_texture_loader;
1825
#[cfg(feature = "hdr")]
1926
mod hdr_texture_loader;
2027
mod image_loader;
2128
#[cfg(feature = "ktx2")]
2229
mod ktx2;
30+
mod texture_atlas;
31+
mod texture_atlas_builder;
2332

2433
#[cfg(feature = "basis-universal")]
2534
pub use compressed_image_saver::*;
2635
#[cfg(feature = "dds")]
2736
pub use dds::*;
37+
pub use dynamic_texture_atlas_builder::*;
2838
#[cfg(feature = "exr")]
2939
pub use exr_texture_loader::*;
3040
#[cfg(feature = "hdr")]
3141
pub use hdr_texture_loader::*;
3242
pub use image_loader::*;
3343
#[cfg(feature = "ktx2")]
3444
pub use ktx2::*;
45+
pub use texture_atlas::*;
46+
pub use texture_atlas_builder::*;
3547

3648
pub(crate) mod image_texture_conversion;
3749
pub use image_texture_conversion::IntoDynamicImageError;

crates/bevy_sprite/src/texture_atlas.rs renamed to crates/bevy_image/src/texture_atlas.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
1-
use bevy_asset::{Asset, AssetId, Assets, Handle};
2-
use bevy_image::Image;
1+
use bevy_app::prelude::*;
2+
use bevy_asset::{Asset, AssetApp as _, AssetId, Assets, Handle};
33
use bevy_math::{URect, UVec2};
44
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
55
#[cfg(feature = "serialize")]
66
use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
77
use bevy_utils::HashMap;
88

9+
use crate::Image;
10+
11+
/// Adds support for texture atlases.
12+
pub struct TextureAtlasPlugin;
13+
14+
impl Plugin for TextureAtlasPlugin {
15+
fn build(&self, app: &mut App) {
16+
app.init_asset::<TextureAtlasLayout>()
17+
.register_asset_reflect::<TextureAtlasLayout>()
18+
.register_type::<TextureAtlas>();
19+
}
20+
}
21+
922
/// Stores a mapping from sub texture handles to the related area index.
1023
///
1124
/// Generated by [`TextureAtlasBuilder`].

crates/bevy_sprite/src/texture_atlas_builder.rs renamed to crates/bevy_image/src/texture_atlas_builder.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
use bevy_asset::AssetId;
2-
use bevy_image::{Image, TextureFormatPixelInfo};
1+
use bevy_asset::{AssetId, RenderAssetUsages};
32
use bevy_math::{URect, UVec2};
4-
use bevy_render::{
5-
render_asset::RenderAssetUsages,
6-
render_resource::{Extent3d, TextureDimension, TextureFormat},
7-
};
83
use bevy_utils::HashMap;
94
use rectangle_pack::{
105
contains_smallest_box, pack_rects, volume_heuristic, GroupedRectsToPlace, PackedLocation,
116
RectToInsert, TargetBin,
127
};
138
use thiserror::Error;
149
use tracing::{debug, error, warn};
10+
use wgpu_types::{Extent3d, TextureDimension, TextureFormat};
1511

12+
use crate::{Image, TextureFormatPixelInfo};
1613
use crate::{TextureAtlasLayout, TextureAtlasSources};
1714

1815
#[derive(Debug, Error)]
@@ -166,8 +163,7 @@ impl<'a> TextureAtlasBuilder<'a> {
166163
/// # use bevy_sprite::prelude::*;
167164
/// # use bevy_ecs::prelude::*;
168165
/// # use bevy_asset::*;
169-
/// # use bevy_render::prelude::*;
170-
/// # use bevy_image::Image;
166+
/// # use bevy_image::prelude::*;
171167
///
172168
/// fn my_system(mut commands: Commands, mut textures: ResMut<Assets<Image>>, mut layouts: ResMut<Assets<TextureAtlasLayout>>) {
173169
/// // Declare your builder

crates/bevy_internal/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ shader_format_spirv = ["bevy_render/shader_format_spirv"]
8989
serialize = [
9090
"bevy_color?/serialize",
9191
"bevy_ecs/serialize",
92+
"bevy_image?/serialize",
9293
"bevy_input/serialize",
9394
"bevy_math/serialize",
9495
"bevy_scene?/serialize",
95-
"bevy_sprite?/serialize",
9696
"bevy_time/serialize",
9797
"bevy_transform/serialize",
9898
"bevy_ui?/serialize",

crates/bevy_sprite/Cargo.toml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ keywords = ["bevy"]
1010

1111
[features]
1212
bevy_sprite_picking_backend = ["bevy_picking", "bevy_window"]
13-
serialize = ["dep:serde"]
1413
webgl = []
1514
webgpu = []
1615

@@ -36,14 +35,10 @@ bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev" }
3635
# other
3736
bytemuck = { version = "1", features = ["derive", "must_cast"] }
3837
fixedbitset = "0.5"
39-
guillotiere = "0.6.0"
40-
thiserror = { version = "2", default-features = false }
4138
derive_more = { version = "1", default-features = false, features = ["from"] }
42-
rectangle-pack = "0.4"
4339
bitflags = "2.3"
4440
radsort = "0.1"
4541
nonmax = "0.5"
46-
serde = { version = "1", features = ["derive"], optional = true }
4742
tracing = { version = "0.1", default-features = false, features = ["std"] }
4843

4944
[lints]

crates/bevy_sprite/src/lib.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,11 @@
1515
1616
extern crate alloc;
1717

18-
mod dynamic_texture_atlas_builder;
1918
mod mesh2d;
2019
#[cfg(feature = "bevy_sprite_picking_backend")]
2120
mod picking_backend;
2221
mod render;
2322
mod sprite;
24-
mod texture_atlas;
25-
mod texture_atlas_builder;
2623
mod texture_slice;
2724

2825
/// The sprite prelude.
@@ -32,27 +29,23 @@ pub mod prelude {
3229
#[doc(hidden)]
3330
pub use crate::{
3431
sprite::{Sprite, SpriteImageMode},
35-
texture_atlas::{TextureAtlas, TextureAtlasLayout, TextureAtlasSources},
3632
texture_slice::{BorderRect, SliceScaleMode, TextureSlice, TextureSlicer},
37-
ColorMaterial, MeshMaterial2d, TextureAtlasBuilder,
33+
ColorMaterial, MeshMaterial2d,
3834
};
3935
}
4036

41-
pub use dynamic_texture_atlas_builder::*;
4237
pub use mesh2d::*;
4338
#[cfg(feature = "bevy_sprite_picking_backend")]
4439
pub use picking_backend::*;
4540
pub use render::*;
4641
pub use sprite::*;
47-
pub use texture_atlas::*;
48-
pub use texture_atlas_builder::*;
4942
pub use texture_slice::*;
5043

5144
use bevy_app::prelude::*;
52-
use bevy_asset::{load_internal_asset, AssetApp, Assets, Handle};
45+
use bevy_asset::{load_internal_asset, Assets, Handle};
5346
use bevy_core_pipeline::core_2d::Transparent2d;
5447
use bevy_ecs::prelude::*;
55-
use bevy_image::Image;
48+
use bevy_image::{prelude::*, TextureAtlasPlugin};
5649
use bevy_render::{
5750
mesh::{Mesh, Mesh2d, MeshAabb},
5851
primitives::Aabb,
@@ -111,13 +104,15 @@ impl Plugin for SpritePlugin {
111104
"render/sprite_view_bindings.wgsl",
112105
Shader::from_wgsl
113106
);
114-
app.init_asset::<TextureAtlasLayout>()
115-
.register_asset_reflect::<TextureAtlasLayout>()
116-
.register_type::<Sprite>()
107+
108+
if !app.is_plugin_added::<TextureAtlasPlugin>() {
109+
app.add_plugins(TextureAtlasPlugin);
110+
}
111+
112+
app.register_type::<Sprite>()
117113
.register_type::<SpriteImageMode>()
118114
.register_type::<TextureSlicer>()
119115
.register_type::<Anchor>()
120-
.register_type::<TextureAtlas>()
121116
.register_type::<Mesh2d>()
122117
.add_plugins((Mesh2dRenderPlugin, ColorMaterialPlugin))
123118
.add_systems(

crates/bevy_sprite/src/picking_backend.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
//! sprites with arbitrary transforms. Picking is done based on sprite bounds, not visible pixels.
33
//! This means a partially transparent sprite is pickable even in its transparent areas.
44
5-
use crate::{Sprite, TextureAtlasLayout};
5+
use crate::Sprite;
66
use bevy_app::prelude::*;
77
use bevy_asset::prelude::*;
88
use bevy_color::Alpha;
99
use bevy_ecs::prelude::*;
10-
use bevy_image::Image;
10+
use bevy_image::prelude::*;
1111
use bevy_math::{prelude::*, FloatExt};
1212
use bevy_picking::backend::prelude::*;
1313
use bevy_reflect::prelude::*;

crates/bevy_sprite/src/render/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use core::ops::Range;
22

3-
use crate::{
4-
texture_atlas::TextureAtlasLayout, ComputedTextureSlices, Sprite, SPRITE_SHADER_HANDLE,
5-
};
3+
use crate::{ComputedTextureSlices, Sprite, SPRITE_SHADER_HANDLE};
64
use bevy_asset::{AssetEvent, AssetId, Assets};
75
use bevy_color::{ColorToComponents, LinearRgba};
86
use bevy_core_pipeline::{
@@ -17,7 +15,7 @@ use bevy_ecs::{
1715
query::ROQueryItem,
1816
system::{lifetimeless::*, SystemParamItem, SystemState},
1917
};
20-
use bevy_image::{BevyDefault, Image, ImageSampler, TextureFormatPixelInfo};
18+
use bevy_image::{BevyDefault, Image, ImageSampler, TextureAtlasLayout, TextureFormatPixelInfo};
2119
use bevy_math::{Affine3A, FloatOrd, Quat, Rect, Vec2, Vec4};
2220
use bevy_render::sync_world::MainEntity;
2321
use bevy_render::view::RenderVisibleEntities;

crates/bevy_sprite/src/sprite.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use bevy_ecs::{
44
component::{require, Component},
55
reflect::ReflectComponent,
66
};
7-
use bevy_image::Image;
7+
use bevy_image::{Image, TextureAtlas, TextureAtlasLayout};
88
use bevy_math::{Rect, UVec2, Vec2};
99
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
1010
use bevy_render::{
@@ -13,7 +13,7 @@ use bevy_render::{
1313
};
1414
use bevy_transform::components::Transform;
1515

16-
use crate::{TextureAtlas, TextureAtlasLayout, TextureSlicer};
16+
use crate::TextureSlicer;
1717

1818
/// Describes a sprite to be rendered to a 2D camera
1919
#[derive(Component, Debug, Default, Clone, Reflect)]
@@ -230,10 +230,11 @@ mod tests {
230230
use bevy_asset::{Assets, RenderAssetUsages};
231231
use bevy_color::Color;
232232
use bevy_image::Image;
233+
use bevy_image::{TextureAtlas, TextureAtlasLayout};
233234
use bevy_math::{Rect, URect, UVec2, Vec2};
234235
use bevy_render::render_resource::{Extent3d, TextureDimension, TextureFormat};
235236

236-
use crate::{Anchor, TextureAtlas, TextureAtlasLayout};
237+
use crate::Anchor;
237238

238239
use super::Sprite;
239240

crates/bevy_text/src/font_atlas.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use bevy_asset::{Assets, Handle};
2-
use bevy_image::{Image, ImageSampler};
2+
use bevy_image::{prelude::*, ImageSampler};
33
use bevy_math::{IVec2, UVec2};
44
use bevy_render::{
55
render_asset::RenderAssetUsages,
66
render_resource::{Extent3d, TextureDimension, TextureFormat},
77
};
8-
use bevy_sprite::{DynamicTextureAtlasBuilder, TextureAtlasLayout};
98
use bevy_utils::HashMap;
109

1110
use crate::{FontSmoothing, GlyphAtlasLocation, TextError};
@@ -21,7 +20,7 @@ use crate::{FontSmoothing, GlyphAtlasLocation, TextError};
2120
/// providing a trade-off between visual quality and performance.
2221
///
2322
/// A [`CacheKey`](cosmic_text::CacheKey) encodes all of the information of a subpixel-offset glyph and is used to
24-
/// find that glyphs raster in a [`TextureAtlas`](bevy_sprite::TextureAtlas) through its corresponding [`GlyphAtlasLocation`].
23+
/// find that glyphs raster in a [`TextureAtlas`] through its corresponding [`GlyphAtlasLocation`].
2524
pub struct FontAtlas {
2625
/// Used to update the [`TextureAtlasLayout`].
2726
pub dynamic_texture_atlas_builder: DynamicTextureAtlasBuilder,

crates/bevy_text/src/font_atlas_set.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ use bevy_ecs::{
33
event::EventReader,
44
system::{ResMut, Resource},
55
};
6-
use bevy_image::Image;
6+
use bevy_image::prelude::*;
77
use bevy_math::{IVec2, UVec2};
88
use bevy_reflect::TypePath;
99
use bevy_render::{
1010
render_asset::RenderAssetUsages,
1111
render_resource::{Extent3d, TextureDimension, TextureFormat},
1212
};
13-
use bevy_sprite::TextureAtlasLayout;
1413
use bevy_utils::HashMap;
1514

1615
use crate::{error::TextError, Font, FontAtlas, FontSmoothing, GlyphAtlasInfo};

crates/bevy_text/src/glyph.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
//! This module exports types related to rendering glyphs.
22
33
use bevy_asset::Handle;
4-
use bevy_image::Image;
4+
use bevy_image::prelude::*;
55
use bevy_math::{IVec2, Vec2};
66
use bevy_reflect::Reflect;
7-
use bevy_sprite::TextureAtlasLayout;
87

98
/// A glyph of a font, typically representing a single character, positioned in screen space.
109
///

crates/bevy_text/src/pipeline.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ use bevy_ecs::{
99
reflect::ReflectComponent,
1010
system::{ResMut, Resource},
1111
};
12-
use bevy_image::Image;
12+
use bevy_image::prelude::*;
1313
use bevy_math::{UVec2, Vec2};
1414
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
15-
use bevy_sprite::TextureAtlasLayout;
1615
use bevy_utils::HashMap;
1716

1817
use cosmic_text::{Attrs, Buffer, Family, Metrics, Shaping, Wrap};

crates/bevy_text/src/text2d.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use bevy_ecs::{
1616
query::{Changed, Without},
1717
system::{Commands, Local, Query, Res, ResMut},
1818
};
19-
use bevy_image::Image;
19+
use bevy_image::prelude::*;
2020
use bevy_math::Vec2;
2121
use bevy_reflect::{prelude::ReflectDefault, Reflect};
2222
use bevy_render::sync_world::TemporaryRenderEntity;
@@ -26,7 +26,7 @@ use bevy_render::{
2626
view::{NoFrustumCulling, ViewVisibility},
2727
Extract,
2828
};
29-
use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, Sprite, TextureAtlasLayout};
29+
use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, Sprite};
3030
use bevy_transform::components::Transform;
3131
use bevy_transform::prelude::GlobalTransform;
3232
use bevy_window::{PrimaryWindow, Window};

0 commit comments

Comments
 (0)