bevy/examples/ui/font_atlas_debug.rs
Michel van der Hulst 6ce7ce208e Change UI coordinate system to have origin at top left corner (#6000)
# Objective
Fixes #5572

## Solution

Approach is to invert the Y-axis of the UI Camera by changing the UI projection matrix to render the UI upside down.

After that I'm trying to fix all issues, that pop up:
- interaction expected the "old" position
- images and text were displayed upside-down
- baseline of text was based on the top of the glyph instead of bottom

... probably a lot more.

---

Result when running examples:
<details>
    <summary>Button example</summary>

main branch:
![button main](https://user-images.githubusercontent.com/4232644/190856087-61dd1d98-42b5-4238-bd97-149744ddfeba.png)
this pr:
![button pr](https://user-images.githubusercontent.com/4232644/190856097-3f4bc97a-ed15-4e97-b7f1-2b2dd6bb8b14.png)

</details>

<details>
    <summary>Text example</summary>

m
![text main](https://user-images.githubusercontent.com/4232644/192142831-4cf19aa1-f49a-485e-af7b-374d6f5c396c.png)
ain branch: 


this pr:
![text pr fixed](https://user-images.githubusercontent.com/4232644/192142829-c433db3b-32e1-4ee8-b493-0b4a4d9c8e70.png)


</details>

<details>
    <summary>Text debug example</summary>

main branch:
![text_debug main](https://user-images.githubusercontent.com/4232644/192142822-940aefa6-e502-410b-8da4-5570f77b5df2.png)

this pr:
![text_debug pr fixed](https://user-images.githubusercontent.com/4232644/194547010-8c968f5c-5a71-4ffc-871d-790c06d48016.png)

</details>

<details>
    <summary>Transparency UI example</summary>

main branch:
![transparency_ui main](https://user-images.githubusercontent.com/4232644/190856172-328c60fe-3622-4598-97d5-2f1595db13b3.png)


this pr:
![transperency_ui pr](https://user-images.githubusercontent.com/4232644/190856179-a2dafb99-41ea-45a9-9dd6-400fa3ef24b9.png)

</details>

<details>
    <summary>UI example</summary>

**ui example**
main branch:
![ui main](https://user-images.githubusercontent.com/4232644/192142812-e20ba31a-6841-46d9-a785-4198cf22dc99.png)

this pr:
![ui pr fixed](https://user-images.githubusercontent.com/4232644/192142788-cc0b74e0-7710-4faa-b5a2-60270a5da77c.png)

</details>

## Changelog
UI coordinate system and cursor position was changed from bottom left origin, y+ up to top left origin, y+ down.

## Migration Guide
All flex layout should be inverted (ColumnReverse => Column, FlexStart => FlexEnd, WrapReverse => Wrap)
System where dealing with cursor position should be changed to account for cursor position being based on the top left instead of bottom left
2022-10-11 12:51:44 +00:00

109 lines
3.2 KiB
Rust

//! This example illustrates how `FontAtlas`'s are populated.
//! Bevy uses `FontAtlas`'s under the hood to optimize text rendering.
use bevy::{prelude::*, text::FontAtlasSet};
fn main() {
App::new()
.init_resource::<State>()
.insert_resource(ClearColor(Color::BLACK))
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.add_system(text_update_system)
.add_system(atlas_render_system)
.run();
}
#[derive(Resource)]
struct State {
atlas_count: u32,
handle: Handle<Font>,
timer: Timer,
}
impl Default for State {
fn default() -> Self {
Self {
atlas_count: 0,
handle: Handle::default(),
timer: Timer::from_seconds(0.05, true),
}
}
}
fn atlas_render_system(
mut commands: Commands,
mut state: ResMut<State>,
font_atlas_sets: Res<Assets<FontAtlasSet>>,
texture_atlases: Res<Assets<TextureAtlas>>,
) {
if let Some(set) = font_atlas_sets.get(&state.handle.as_weak::<FontAtlasSet>()) {
if let Some((_size, font_atlas)) = set.iter().next() {
let x_offset = state.atlas_count as f32;
if state.atlas_count == font_atlas.len() as u32 {
return;
}
let texture_atlas = texture_atlases
.get(&font_atlas[state.atlas_count as usize].texture_atlas)
.unwrap();
state.atlas_count += 1;
commands.spawn(ImageBundle {
image: texture_atlas.texture.clone().into(),
style: Style {
position_type: PositionType::Absolute,
position: UiRect {
top: Val::Px(0.0),
left: Val::Px(512.0 * x_offset),
..default()
},
..default()
},
..default()
});
}
}
}
fn text_update_system(mut state: ResMut<State>, time: Res<Time>, mut query: Query<&mut Text>) {
if state.timer.tick(time.delta()).finished() {
for mut text in &mut query {
let c = rand::random::<u8>() as char;
let string = &mut text.sections[0].value;
if !string.contains(c) {
string.push(c);
}
}
state.timer.reset();
}
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut state: ResMut<State>) {
let font_handle = asset_server.load("fonts/FiraSans-Bold.ttf");
state.handle = font_handle.clone();
commands.spawn(Camera2dBundle::default());
commands
.spawn(NodeBundle {
background_color: Color::NONE.into(),
style: Style {
position_type: PositionType::Absolute,
position: UiRect {
bottom: Val::Px(0.0),
..default()
},
..default()
},
..default()
})
.with_children(|parent| {
parent.spawn(TextBundle::from_section(
"a",
TextStyle {
font: font_handle,
font_size: 60.0,
color: Color::YELLOW,
},
));
});
}