diff --git a/crates/bevy_image/Cargo.toml b/crates/bevy_image/Cargo.toml index 3a2de913c4..ce23a8b15d 100644 --- a/crates/bevy_image/Cargo.toml +++ b/crates/bevy_image/Cargo.toml @@ -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", @@ -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 @@ -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 diff --git a/crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs b/crates/bevy_image/src/dynamic_texture_atlas_builder.rs similarity index 96% rename from crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs rename to crates/bevy_image/src/dynamic_texture_atlas_builder.rs index 34e3ae87a7..8944e74e74 100644 --- a/crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs +++ b/crates/bevy_image/src/dynamic_texture_atlas_builder.rs @@ -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. diff --git a/crates/bevy_image/src/lib.rs b/crates/bevy_image/src/lib.rs index 2952bcec7c..4fe067d253 100644 --- a/crates/bevy_image/src/lib.rs +++ b/crates/bevy_image/src/lib.rs @@ -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; @@ -13,6 +19,7 @@ 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")] @@ -20,11 +27,14 @@ 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")] @@ -32,6 +42,8 @@ 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; diff --git a/crates/bevy_sprite/src/texture_atlas.rs b/crates/bevy_image/src/texture_atlas.rs similarity index 94% rename from crates/bevy_sprite/src/texture_atlas.rs rename to crates/bevy_image/src/texture_atlas.rs index 797fb4aa20..1e349f152d 100644 --- a/crates/bevy_sprite/src/texture_atlas.rs +++ b/crates/bevy_image/src/texture_atlas.rs @@ -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::() + .register_asset_reflect::() + .register_type::(); + } +} + /// Stores a mapping from sub texture handles to the related area index. /// /// Generated by [`TextureAtlasBuilder`]. diff --git a/crates/bevy_sprite/src/texture_atlas_builder.rs b/crates/bevy_image/src/texture_atlas_builder.rs similarity index 97% rename from crates/bevy_sprite/src/texture_atlas_builder.rs rename to crates/bevy_image/src/texture_atlas_builder.rs index bfc577db3e..0b0889d97c 100644 --- a/crates/bevy_sprite/src/texture_atlas_builder.rs +++ b/crates/bevy_image/src/texture_atlas_builder.rs @@ -1,10 +1,5 @@ -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, @@ -12,7 +7,9 @@ use rectangle_pack::{ }; 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)] @@ -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>, mut layouts: ResMut>) { /// // Declare your builder diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index cacac293fe..7c8030edfb 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -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", diff --git a/crates/bevy_sprite/Cargo.toml b/crates/bevy_sprite/Cargo.toml index 76a8682835..fc43163170 100644 --- a/crates/bevy_sprite/Cargo.toml +++ b/crates/bevy_sprite/Cargo.toml @@ -10,7 +10,6 @@ keywords = ["bevy"] [features] bevy_sprite_picking_backend = ["bevy_picking", "bevy_window"] -serialize = ["dep:serde"] webgl = [] webgpu = [] @@ -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] diff --git a/crates/bevy_sprite/src/lib.rs b/crates/bevy_sprite/src/lib.rs index 173ef17f7d..fc6c4b5d5d 100644 --- a/crates/bevy_sprite/src/lib.rs +++ b/crates/bevy_sprite/src/lib.rs @@ -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. @@ -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, @@ -111,13 +104,15 @@ impl Plugin for SpritePlugin { "render/sprite_view_bindings.wgsl", Shader::from_wgsl ); - app.init_asset::() - .register_asset_reflect::() - .register_type::() + + if !app.is_plugin_added::() { + app.add_plugins(TextureAtlasPlugin); + } + + app.register_type::() .register_type::() .register_type::() .register_type::() - .register_type::() .register_type::() .add_plugins((Mesh2dRenderPlugin, ColorMaterialPlugin)) .add_systems( diff --git a/crates/bevy_sprite/src/picking_backend.rs b/crates/bevy_sprite/src/picking_backend.rs index aef7bc5c24..435137b22f 100644 --- a/crates/bevy_sprite/src/picking_backend.rs +++ b/crates/bevy_sprite/src/picking_backend.rs @@ -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::*; diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index 014fd779ee..62a92b4896 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -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::{ @@ -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; diff --git a/crates/bevy_sprite/src/sprite.rs b/crates/bevy_sprite/src/sprite.rs index c6550f51d7..82101a8b38 100644 --- a/crates/bevy_sprite/src/sprite.rs +++ b/crates/bevy_sprite/src/sprite.rs @@ -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::{ @@ -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)] @@ -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; diff --git a/crates/bevy_text/src/font_atlas.rs b/crates/bevy_text/src/font_atlas.rs index 4ce4ea6207..f053bb6ab1 100644 --- a/crates/bevy_text/src/font_atlas.rs +++ b/crates/bevy_text/src/font_atlas.rs @@ -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}; @@ -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, diff --git a/crates/bevy_text/src/font_atlas_set.rs b/crates/bevy_text/src/font_atlas_set.rs index 5461e7af1f..4028f7eab8 100644 --- a/crates/bevy_text/src/font_atlas_set.rs +++ b/crates/bevy_text/src/font_atlas_set.rs @@ -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}; diff --git a/crates/bevy_text/src/glyph.rs b/crates/bevy_text/src/glyph.rs index b5295c655e..6de501266c 100644 --- a/crates/bevy_text/src/glyph.rs +++ b/crates/bevy_text/src/glyph.rs @@ -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. /// diff --git a/crates/bevy_text/src/pipeline.rs b/crates/bevy_text/src/pipeline.rs index 6ff1e306db..8b2e4e3eb3 100644 --- a/crates/bevy_text/src/pipeline.rs +++ b/crates/bevy_text/src/pipeline.rs @@ -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}; diff --git a/crates/bevy_text/src/text2d.rs b/crates/bevy_text/src/text2d.rs index 970b226f81..893f127b8b 100644 --- a/crates/bevy_text/src/text2d.rs +++ b/crates/bevy_text/src/text2d.rs @@ -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; @@ -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}; diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index b69d241dd9..4a0147c32a 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -20,7 +20,7 @@ use bevy_core_pipeline::core_3d::graph::{Core3d, Node3d}; use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d}; use bevy_ecs::entity::{EntityHashMap, EntityHashSet}; use bevy_ecs::prelude::*; -use bevy_image::Image; +use bevy_image::prelude::*; use bevy_math::{FloatOrd, Mat4, Rect, UVec4, Vec2, Vec3, Vec3Swizzles, Vec4Swizzles}; use bevy_render::render_phase::ViewSortedRenderPhases; use bevy_render::sync_world::MainEntity; @@ -42,7 +42,6 @@ use bevy_render::{ view::ViewVisibility, ExtractSchedule, Render, }; -use bevy_sprite::TextureAtlasLayout; use bevy_sprite::{BorderRect, SpriteAssetEvents}; #[cfg(feature = "bevy_ui_debug")] pub use debug_overlay::UiDebugOptions; diff --git a/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs b/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs index 29c10dec09..9bee1ea8df 100644 --- a/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs @@ -11,7 +11,7 @@ use bevy_ecs::{ *, }, }; -use bevy_image::{BevyDefault, Image}; +use bevy_image::prelude::*; use bevy_math::{FloatOrd, Mat4, Rect, Vec2, Vec4Swizzles}; use bevy_render::sync_world::MainEntity; use bevy_render::{ @@ -24,9 +24,7 @@ use bevy_render::{ view::*, Extract, ExtractSchedule, Render, RenderSet, }; -use bevy_sprite::{ - SliceScaleMode, SpriteAssetEvents, SpriteImageMode, TextureAtlasLayout, TextureSlicer, -}; +use bevy_sprite::{SliceScaleMode, SpriteAssetEvents, SpriteImageMode, TextureSlicer}; use bevy_transform::prelude::GlobalTransform; use bevy_utils::HashMap; use binding_types::{sampler, texture_2d}; diff --git a/crates/bevy_ui/src/widget/image.rs b/crates/bevy_ui/src/widget/image.rs index 55fb343737..e34efdc715 100644 --- a/crates/bevy_ui/src/widget/image.rs +++ b/crates/bevy_ui/src/widget/image.rs @@ -2,11 +2,11 @@ use crate::{ContentSize, Measure, MeasureArgs, Node, NodeMeasure, UiScale}; use bevy_asset::{Assets, Handle}; use bevy_color::Color; use bevy_ecs::prelude::*; -use bevy_image::Image; +use bevy_image::prelude::*; use bevy_math::{Rect, UVec2, Vec2}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::texture::TRANSPARENT_IMAGE_HANDLE; -use bevy_sprite::{TextureAtlas, TextureAtlasLayout, TextureSlicer}; +use bevy_sprite::TextureSlicer; use bevy_window::{PrimaryWindow, Window}; use taffy::{MaybeMath, MaybeResolve}; diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index 62cc3f649d..9274ff87ea 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -14,11 +14,10 @@ use bevy_ecs::{ system::{Local, Query, Res, ResMut}, world::{Mut, Ref}, }; -use bevy_image::Image; +use bevy_image::prelude::*; use bevy_math::Vec2; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::camera::Camera; -use bevy_sprite::TextureAtlasLayout; use bevy_text::{ scale_value, ComputedTextBlock, CosmicFontSystem, Font, FontAtlasSets, LineBreak, SwashCache, TextBounds, TextColor, TextError, TextFont, TextLayout, TextLayoutInfo, TextMeasureInfo,