You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Objective
Ultimately, I'd like to modify our font atlas creation systems so that
they are able to resize the font atlases as more glyphs are added. At
the moment, they create a new 512x512 atlas every time one fills up.
With large font sizes and many glyphs, your glyphs may end up spread out
across several atlases.
The goal would be to render text more efficiently, because glyphs spread
across fewer textures could benefit more from batching.
`AtlasAllocator` already has support for growing atlases, but we don't
currently have a way of growing a texture while keeping the pixel data
intact.
## Solution
Add a new method to `Image`: `resize_in_place` and a test for it.
## Testing
Ran the new test, and also a little demo comparing this side-by-side
with `resize`.
<details>
<summary>Expand Code</summary>
```rust
//! Testing ground for #19410
use bevy::prelude::*;
use bevy_render::render_resource::Extent3d;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, test)
.init_resource::<Size>()
.insert_resource(FillColor(Hsla::hsl(0.0, 1.0, 0.7)))
.run();
}
#[derive(Resource, Default)]
struct Size(Option<UVec2>);
#[derive(Resource)]
struct FillColor(Hsla);
#[derive(Component)]
struct InPlace;
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2d);
commands.spawn((
Transform::from_xyz(220.0, 0.0, 0.0),
Sprite::from_image(asset_server.load("branding/bevy_bird_dark.png")),
));
commands.spawn((
InPlace,
Transform::from_xyz(-220.0, 0.0, 0.0),
Sprite::from_image(asset_server.load("branding/icon.png")),
));
}
fn test(
sprites: Query<(&Sprite, Has<InPlace>)>,
mut images: ResMut<Assets<Image>>,
mut new_size: ResMut<Size>,
mut dir: Local<IVec2>,
mut color: ResMut<FillColor>,
) -> Result {
for (sprite, in_place) in &sprites {
let image = images.get_mut(&sprite.image).ok_or("Image not found")?;
let size = new_size.0.get_or_insert(image.size());
if *dir == IVec2::ZERO {
*dir = IVec2::splat(1);
}
*size = size.saturating_add_signed(*dir);
if size.x > 400 || size.x < 150 {
*dir = *dir * -1;
}
color.0 = color.0.rotate_hue(1.0);
if in_place {
image.resize_in_place_2d(
Extent3d {
width: size.x,
height: size.y,
..default()
},
&Srgba::from(color.0).to_u8_array(),
)?;
} else {
image.resize(Extent3d {
width: size.x,
height: size.y,
..default()
});
}
}
Ok(())
}
```
</details>
https://github.com/user-attachments/assets/6b2d0ec3-6a6e-4da1-98aa-29e7162f16fa
## Alternatives
I think that this might be useful functionality outside of the font
atlas scenario, but we *could* just increase the initial font atlas
size, make it configurable, and/or size font atlases according to device
limits. It's not totally clear to me how to accomplish that last idea.
0 commit comments