Skip to content

Commit

Permalink
Move TextureAtlas and friends into bevy_image (#17219)
Browse files Browse the repository at this point in the history
# 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.
  • Loading branch information
mgi388 authored Jan 7, 2025
1 parent 3578f9e commit e24ae6c
Show file tree
Hide file tree
Showing 20 changed files with 74 additions and 64 deletions.
9 changes: 9 additions & 0 deletions crates/bevy_image/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ qoi = ["image/qoi"]
tga = ["image/tga"]
tiff = ["image/tiff"]
webp = ["image/webp"]
serialize = []

# For ktx2 supercompression
zlib = ["flate2"]
zstd = ["ruzstd"]

[dependencies]
# bevy
bevy_app = { path = "../bevy_app", version = "0.16.0-dev" }
bevy_asset = { path = "../bevy_asset", version = "0.16.0-dev" }
bevy_color = { path = "../bevy_color", version = "0.16.0-dev", features = [
"serialize",
Expand All @@ -55,6 +58,8 @@ wgpu = { version = "23.0.1", default-features = false }
serde = { version = "1", features = ["derive"] }
thiserror = { version = "2", default-features = false }
futures-lite = "2.0.1"
guillotiere = "0.6.0"
rectangle-pack = "0.4"
ddsfile = { version = "0.5.2", optional = true }
ktx2 = { version = "0.3.0", optional = true }
# For ktx2 supercompression
Expand All @@ -64,6 +69,10 @@ ruzstd = { version = "0.7.0", optional = true }
basis-universal = { version = "0.3.0", optional = true }
tracing = { version = "0.1", default-features = false, features = ["std"] }

[dev-dependencies]
bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" }
bevy_sprite = { path = "../bevy_sprite", version = "0.16.0-dev" }

[lints]
workspace = true

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::TextureAtlasLayout;
use bevy_image::{Image, TextureFormatPixelInfo};
use crate::{Image, TextureAtlasLayout, TextureFormatPixelInfo as _};
use bevy_asset::RenderAssetUsages;
use bevy_math::{URect, UVec2};
use bevy_render::render_asset::RenderAssetUsages;
use guillotiere::{size2, Allocation, AtlasAllocator};

/// Helper utility to update [`TextureAtlasLayout`] on the fly.
Expand Down
14 changes: 13 additions & 1 deletion crates/bevy_image/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#![expect(missing_docs, reason = "Not all docs are written yet, see #3492.")]
#![allow(unsafe_code)]

extern crate alloc;

pub mod prelude {
pub use crate::{BevyDefault as _, Image, ImageFormat, TextureError};
pub use crate::{
dynamic_texture_atlas_builder::DynamicTextureAtlasBuilder,
texture_atlas::{TextureAtlas, TextureAtlasLayout, TextureAtlasSources},
BevyDefault as _, Image, ImageFormat, TextureAtlasBuilder, TextureError,
};
}

mod image;
Expand All @@ -13,25 +19,31 @@ mod basis;
mod compressed_image_saver;
#[cfg(feature = "dds")]
mod dds;
mod dynamic_texture_atlas_builder;
#[cfg(feature = "exr")]
mod exr_texture_loader;
#[cfg(feature = "hdr")]
mod hdr_texture_loader;
mod image_loader;
#[cfg(feature = "ktx2")]
mod ktx2;
mod texture_atlas;
mod texture_atlas_builder;

#[cfg(feature = "basis-universal")]
pub use compressed_image_saver::*;
#[cfg(feature = "dds")]
pub use dds::*;
pub use dynamic_texture_atlas_builder::*;
#[cfg(feature = "exr")]
pub use exr_texture_loader::*;
#[cfg(feature = "hdr")]
pub use hdr_texture_loader::*;
pub use image_loader::*;
#[cfg(feature = "ktx2")]
pub use ktx2::*;
pub use texture_atlas::*;
pub use texture_atlas_builder::*;

pub(crate) mod image_texture_conversion;
pub use image_texture_conversion::IntoDynamicImageError;
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
use bevy_asset::{Asset, AssetId, Assets, Handle};
use bevy_image::Image;
use bevy_app::prelude::*;
use bevy_asset::{Asset, AssetApp as _, AssetId, Assets, Handle};
use bevy_math::{URect, UVec2};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
#[cfg(feature = "serialize")]
use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
use bevy_utils::HashMap;

use crate::Image;

/// Adds support for texture atlases.
pub struct TextureAtlasPlugin;

impl Plugin for TextureAtlasPlugin {
fn build(&self, app: &mut App) {
app.init_asset::<TextureAtlasLayout>()
.register_asset_reflect::<TextureAtlasLayout>()
.register_type::<TextureAtlas>();
}
}

/// Stores a mapping from sub texture handles to the related area index.
///
/// Generated by [`TextureAtlasBuilder`].
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
use bevy_asset::AssetId;
use bevy_image::{Image, TextureFormatPixelInfo};
use bevy_asset::{AssetId, RenderAssetUsages};
use bevy_math::{URect, UVec2};
use bevy_render::{
render_asset::RenderAssetUsages,
render_resource::{Extent3d, TextureDimension, TextureFormat},
};
use bevy_utils::HashMap;
use rectangle_pack::{
contains_smallest_box, pack_rects, volume_heuristic, GroupedRectsToPlace, PackedLocation,
RectToInsert, TargetBin,
};
use thiserror::Error;
use tracing::{debug, error, warn};
use wgpu_types::{Extent3d, TextureDimension, TextureFormat};

use crate::{Image, TextureFormatPixelInfo};
use crate::{TextureAtlasLayout, TextureAtlasSources};

#[derive(Debug, Error)]
Expand Down Expand Up @@ -166,8 +163,7 @@ impl<'a> TextureAtlasBuilder<'a> {
/// # use bevy_sprite::prelude::*;
/// # use bevy_ecs::prelude::*;
/// # use bevy_asset::*;
/// # use bevy_render::prelude::*;
/// # use bevy_image::Image;
/// # use bevy_image::prelude::*;
///
/// fn my_system(mut commands: Commands, mut textures: ResMut<Assets<Image>>, mut layouts: ResMut<Assets<TextureAtlasLayout>>) {
/// // Declare your builder
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ shader_format_spirv = ["bevy_render/shader_format_spirv"]
serialize = [
"bevy_color?/serialize",
"bevy_ecs/serialize",
"bevy_image?/serialize",
"bevy_input/serialize",
"bevy_math/serialize",
"bevy_scene?/serialize",
"bevy_sprite?/serialize",
"bevy_time/serialize",
"bevy_transform/serialize",
"bevy_ui?/serialize",
Expand Down
5 changes: 0 additions & 5 deletions crates/bevy_sprite/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ keywords = ["bevy"]

[features]
bevy_sprite_picking_backend = ["bevy_picking", "bevy_window"]
serialize = ["dep:serde"]
webgl = []
webgpu = []

Expand All @@ -36,14 +35,10 @@ bevy_derive = { path = "../bevy_derive", version = "0.16.0-dev" }
# other
bytemuck = { version = "1", features = ["derive", "must_cast"] }
fixedbitset = "0.5"
guillotiere = "0.6.0"
thiserror = { version = "2", default-features = false }
derive_more = { version = "1", default-features = false, features = ["from"] }
rectangle-pack = "0.4"
bitflags = "2.3"
radsort = "0.1"
nonmax = "0.5"
serde = { version = "1", features = ["derive"], optional = true }
tracing = { version = "0.1", default-features = false, features = ["std"] }

[lints]
Expand Down
23 changes: 9 additions & 14 deletions crates/bevy_sprite/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@
extern crate alloc;

mod dynamic_texture_atlas_builder;
mod mesh2d;
#[cfg(feature = "bevy_sprite_picking_backend")]
mod picking_backend;
mod render;
mod sprite;
mod texture_atlas;
mod texture_atlas_builder;
mod texture_slice;

/// The sprite prelude.
Expand All @@ -32,27 +29,23 @@ pub mod prelude {
#[doc(hidden)]
pub use crate::{
sprite::{Sprite, SpriteImageMode},
texture_atlas::{TextureAtlas, TextureAtlasLayout, TextureAtlasSources},
texture_slice::{BorderRect, SliceScaleMode, TextureSlice, TextureSlicer},
ColorMaterial, MeshMaterial2d, TextureAtlasBuilder,
ColorMaterial, MeshMaterial2d,
};
}

pub use dynamic_texture_atlas_builder::*;
pub use mesh2d::*;
#[cfg(feature = "bevy_sprite_picking_backend")]
pub use picking_backend::*;
pub use render::*;
pub use sprite::*;
pub use texture_atlas::*;
pub use texture_atlas_builder::*;
pub use texture_slice::*;

use bevy_app::prelude::*;
use bevy_asset::{load_internal_asset, AssetApp, Assets, Handle};
use bevy_asset::{load_internal_asset, Assets, Handle};
use bevy_core_pipeline::core_2d::Transparent2d;
use bevy_ecs::prelude::*;
use bevy_image::Image;
use bevy_image::{prelude::*, TextureAtlasPlugin};
use bevy_render::{
mesh::{Mesh, Mesh2d, MeshAabb},
primitives::Aabb,
Expand Down Expand Up @@ -111,13 +104,15 @@ impl Plugin for SpritePlugin {
"render/sprite_view_bindings.wgsl",
Shader::from_wgsl
);
app.init_asset::<TextureAtlasLayout>()
.register_asset_reflect::<TextureAtlasLayout>()
.register_type::<Sprite>()

if !app.is_plugin_added::<TextureAtlasPlugin>() {
app.add_plugins(TextureAtlasPlugin);
}

app.register_type::<Sprite>()
.register_type::<SpriteImageMode>()
.register_type::<TextureSlicer>()
.register_type::<Anchor>()
.register_type::<TextureAtlas>()
.register_type::<Mesh2d>()
.add_plugins((Mesh2dRenderPlugin, ColorMaterialPlugin))
.add_systems(
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_sprite/src/picking_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
//! sprites with arbitrary transforms. Picking is done based on sprite bounds, not visible pixels.
//! This means a partially transparent sprite is pickable even in its transparent areas.
use crate::{Sprite, TextureAtlasLayout};
use crate::Sprite;
use bevy_app::prelude::*;
use bevy_asset::prelude::*;
use bevy_color::Alpha;
use bevy_ecs::prelude::*;
use bevy_image::Image;
use bevy_image::prelude::*;
use bevy_math::{prelude::*, FloatExt};
use bevy_picking::backend::prelude::*;
use bevy_reflect::prelude::*;
Expand Down
6 changes: 2 additions & 4 deletions crates/bevy_sprite/src/render/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use core::ops::Range;

use crate::{
texture_atlas::TextureAtlasLayout, ComputedTextureSlices, Sprite, SPRITE_SHADER_HANDLE,
};
use crate::{ComputedTextureSlices, Sprite, SPRITE_SHADER_HANDLE};
use bevy_asset::{AssetEvent, AssetId, Assets};
use bevy_color::{ColorToComponents, LinearRgba};
use bevy_core_pipeline::{
Expand All @@ -17,7 +15,7 @@ use bevy_ecs::{
query::ROQueryItem,
system::{lifetimeless::*, SystemParamItem, SystemState},
};
use bevy_image::{BevyDefault, Image, ImageSampler, TextureFormatPixelInfo};
use bevy_image::{BevyDefault, Image, ImageSampler, TextureAtlasLayout, TextureFormatPixelInfo};
use bevy_math::{Affine3A, FloatOrd, Quat, Rect, Vec2, Vec4};
use bevy_render::sync_world::MainEntity;
use bevy_render::view::RenderVisibleEntities;
Expand Down
7 changes: 4 additions & 3 deletions crates/bevy_sprite/src/sprite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy_ecs::{
component::{require, Component},
reflect::ReflectComponent,
};
use bevy_image::Image;
use bevy_image::{Image, TextureAtlas, TextureAtlasLayout};
use bevy_math::{Rect, UVec2, Vec2};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_render::{
Expand All @@ -13,7 +13,7 @@ use bevy_render::{
};
use bevy_transform::components::Transform;

use crate::{TextureAtlas, TextureAtlasLayout, TextureSlicer};
use crate::TextureSlicer;

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

use crate::{Anchor, TextureAtlas, TextureAtlasLayout};
use crate::Anchor;

use super::Sprite;

Expand Down
5 changes: 2 additions & 3 deletions crates/bevy_text/src/font_atlas.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use bevy_asset::{Assets, Handle};
use bevy_image::{Image, ImageSampler};
use bevy_image::{prelude::*, ImageSampler};
use bevy_math::{IVec2, UVec2};
use bevy_render::{
render_asset::RenderAssetUsages,
render_resource::{Extent3d, TextureDimension, TextureFormat},
};
use bevy_sprite::{DynamicTextureAtlasBuilder, TextureAtlasLayout};
use bevy_utils::HashMap;

use crate::{FontSmoothing, GlyphAtlasLocation, TextError};
Expand All @@ -21,7 +20,7 @@ use crate::{FontSmoothing, GlyphAtlasLocation, TextError};
/// providing a trade-off between visual quality and performance.
///
/// A [`CacheKey`](cosmic_text::CacheKey) encodes all of the information of a subpixel-offset glyph and is used to
/// find that glyphs raster in a [`TextureAtlas`](bevy_sprite::TextureAtlas) through its corresponding [`GlyphAtlasLocation`].
/// find that glyphs raster in a [`TextureAtlas`] through its corresponding [`GlyphAtlasLocation`].
pub struct FontAtlas {
/// Used to update the [`TextureAtlasLayout`].
pub dynamic_texture_atlas_builder: DynamicTextureAtlasBuilder,
Expand Down
3 changes: 1 addition & 2 deletions crates/bevy_text/src/font_atlas_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ use bevy_ecs::{
event::EventReader,
system::{ResMut, Resource},
};
use bevy_image::Image;
use bevy_image::prelude::*;
use bevy_math::{IVec2, UVec2};
use bevy_reflect::TypePath;
use bevy_render::{
render_asset::RenderAssetUsages,
render_resource::{Extent3d, TextureDimension, TextureFormat},
};
use bevy_sprite::TextureAtlasLayout;
use bevy_utils::HashMap;

use crate::{error::TextError, Font, FontAtlas, FontSmoothing, GlyphAtlasInfo};
Expand Down
3 changes: 1 addition & 2 deletions crates/bevy_text/src/glyph.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
//! This module exports types related to rendering glyphs.
use bevy_asset::Handle;
use bevy_image::Image;
use bevy_image::prelude::*;
use bevy_math::{IVec2, Vec2};
use bevy_reflect::Reflect;
use bevy_sprite::TextureAtlasLayout;

/// A glyph of a font, typically representing a single character, positioned in screen space.
///
Expand Down
3 changes: 1 addition & 2 deletions crates/bevy_text/src/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ use bevy_ecs::{
reflect::ReflectComponent,
system::{ResMut, Resource},
};
use bevy_image::Image;
use bevy_image::prelude::*;
use bevy_math::{UVec2, Vec2};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_sprite::TextureAtlasLayout;
use bevy_utils::HashMap;

use cosmic_text::{Attrs, Buffer, Family, Metrics, Shaping, Wrap};
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_text/src/text2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use bevy_ecs::{
query::{Changed, Without},
system::{Commands, Local, Query, Res, ResMut},
};
use bevy_image::Image;
use bevy_image::prelude::*;
use bevy_math::Vec2;
use bevy_reflect::{prelude::ReflectDefault, Reflect};
use bevy_render::sync_world::TemporaryRenderEntity;
Expand All @@ -26,7 +26,7 @@ use bevy_render::{
view::{NoFrustumCulling, ViewVisibility},
Extract,
};
use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, Sprite, TextureAtlasLayout};
use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, Sprite};
use bevy_transform::components::Transform;
use bevy_transform::prelude::GlobalTransform;
use bevy_window::{PrimaryWindow, Window};
Expand Down
Loading

0 comments on commit e24ae6c

Please sign in to comment.