Skip to content

Commit 6e29a94

Browse files
committed
Render text in UI
1 parent feb158d commit 6e29a94

File tree

7 files changed

+102
-70
lines changed

7 files changed

+102
-70
lines changed

pipelined/bevy_text2/src/text.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ impl Text {
1616
///
1717
/// ```
1818
/// # use bevy_asset::{AssetServer, Handle};
19-
/// # use bevy_render::color::Color;
19+
/// # use bevy_render2::color::Color;
2020
/// # use bevy_text2::{Font, Text, TextAlignment, TextStyle};
2121
/// # use glyph_brush_layout::{HorizontalAlign, VerticalAlign};
2222
/// #

pipelined/bevy_ui2/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ impl Plugin for UiPlugin {
6060
CoreStage::PreUpdate,
6161
ui_focus_system.label(UiSystem::Focus).after(InputSystem),
6262
)
63-
// // add these stages to front because these must run before transform update systems
64-
// .add_system_to_stage(
65-
// CoreStage::PostUpdate,
66-
// widget::text_system.before(UiSystem::Flex),
67-
// )
63+
// add these stages to front because these must run before transform update systems
64+
.add_system_to_stage(
65+
CoreStage::PostUpdate,
66+
widget::text_system.before(UiSystem::Flex),
67+
)
6868
.add_system_to_stage(
6969
CoreStage::PostUpdate,
7070
widget::image_node_system.before(UiSystem::Flex),

pipelined/bevy_ui2/src/render/mod.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod camera;
22
pub mod shaders;
3+
pub mod text;
34
pub mod ui_pass;
45

56
use bevy_app::App;
@@ -24,6 +25,7 @@ use bevy_render2::{
2425
view::{ViewUniformOffset, ViewUniforms},
2526
RenderApp, RenderStage,
2627
};
28+
use bevy_sprite2::Rect;
2729
use bevy_transform::components::GlobalTransform;
2830

2931
use bevy_utils::HashMap;
@@ -66,6 +68,7 @@ pub fn build_ui_render(app: &mut App) {
6668
.init_resource::<ImageBindGroups>()
6769
.add_system_to_stage(RenderStage::Extract, camera::extract_ui_camera)
6870
.add_system_to_stage(RenderStage::Extract, extract_uinodes)
71+
.add_system_to_stage(RenderStage::Extract, text::extract_text_uinodes)
6972
.add_system_to_stage(RenderStage::Prepare, camera::prepare_ui_views)
7073
.add_system_to_stage(RenderStage::Prepare, prepare_uinodes)
7174
.add_system_to_stage(RenderStage::Queue, queue_uinodes)
@@ -123,6 +126,7 @@ pub struct ExtractedUiNode {
123126
size: Vec2,
124127
color: Vec4,
125128
texture: Option<Handle<Image>>,
129+
uv_rect: Rect,
126130
}
127131

128132
pub fn extract_uinodes(
@@ -154,6 +158,10 @@ pub fn extract_uinodes(
154158
size: uinode.size,
155159
color: color.as_rgba_linear().into(), // FIXME: is that always correct?
156160
texture,
161+
uv_rect: Rect {
162+
min: Vec2::new(0., 0.),
163+
max: Vec2::new(1., 1.),
164+
},
157165
},),
158166
));
159167
}
@@ -168,6 +176,7 @@ struct UiVertexInstance {
168176
color: Vec4,
169177
size: Vec2,
170178
_padding: Vec2, // FIXME: This is due to Mat4 having `repr(align(16))`
179+
uv_rect: Vec4,
171180
}
172181

173182
pub struct UiMeta {
@@ -206,6 +215,12 @@ pub fn prepare_uinodes(
206215
color: extracted_uinode.color,
207216
size: extracted_uinode.size,
208217
_padding: Default::default(),
218+
uv_rect: Vec4::new(
219+
extracted_uinode.uv_rect.min.x,
220+
extracted_uinode.uv_rect.min.y,
221+
extracted_uinode.uv_rect.max.x,
222+
extracted_uinode.uv_rect.max.y,
223+
),
209224
});
210225
}
211226

pipelined/bevy_ui2/src/render/shaders.rs

+7
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ impl FromWorld for UiShaders {
152152
as BufferAddress,
153153
shader_location: 6,
154154
},
155+
// uv_rect
156+
VertexAttribute {
157+
format: VertexFormat::Float32x4,
158+
offset: (size_of::<[f32; 4]>() * 5 + 2 * size_of::<[f32; 2]>())
159+
as BufferAddress,
160+
shader_location: 7,
161+
},
155162
],
156163
},
157164
],

pipelined/bevy_ui2/src/render/text.rs

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use bevy_asset::Assets;
2+
use bevy_ecs::prelude::*;
3+
use bevy_math::Mat4;
4+
use bevy_sprite2::{Rect, TextureAtlas};
5+
use bevy_text2::{DefaultTextPipeline, Text};
6+
use bevy_transform::components::GlobalTransform;
7+
use bevy_window::Windows;
8+
9+
use crate::{ExtractedUiNode, UiNode};
10+
11+
pub fn extract_text_uinodes(
12+
mut commands: Commands,
13+
texture_atlases: Res<Assets<TextureAtlas>>,
14+
text_pipeline: Res<DefaultTextPipeline>,
15+
windows: Res<Windows>,
16+
uinode_query: Query<(Entity, &UiNode, &GlobalTransform, &Text)>,
17+
) {
18+
for (entity, uinode, transform, text) in uinode_query.iter() {
19+
if let Some(text_layout) = text_pipeline.get_glyphs(&entity) {
20+
let text_glyphs = &text_layout.glyphs;
21+
let alignment_offset = (uinode.size / -2.0).extend(0.0);
22+
let scale_factor = if let Some(window) = windows.get_primary() {
23+
window.scale_factor() as f32
24+
} else {
25+
1.
26+
};
27+
28+
for text_glyph in text_glyphs {
29+
let color = text.sections[text_glyph.section_index]
30+
.style
31+
.color
32+
.as_rgba_linear()
33+
.into();
34+
let atlas = texture_atlases
35+
.get(text_glyph.atlas_info.texture_atlas.clone())
36+
.unwrap();
37+
let texture = Some(atlas.texture.clone());
38+
let index = text_glyph.atlas_info.glyph_index;
39+
let glyph_rect = atlas.textures[index as usize];
40+
let uv_rect = Rect {
41+
min: glyph_rect.min / atlas.size,
42+
max: glyph_rect.max / atlas.size,
43+
};
44+
let size = glyph_rect.size();
45+
46+
let transform =
47+
Mat4::from_rotation_translation(transform.rotation, transform.translation)
48+
* Mat4::from_scale(transform.scale / scale_factor)
49+
* Mat4::from_translation(
50+
alignment_offset * scale_factor + text_glyph.position.extend(0.),
51+
);
52+
53+
commands.spawn_and_forget((ExtractedUiNode {
54+
transform,
55+
size,
56+
color,
57+
texture,
58+
uv_rect,
59+
},));
60+
}
61+
}
62+
}
63+
}

pipelined/bevy_ui2/src/render/ui.wgsl

+7-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct Instance {
1919
[[location(4)]] color: vec4<f32>;
2020
[[location(5)]] size: vec2<f32>;
2121
[[location(6)]] padding: vec2<f32>;
22+
[[location(7)]] uv_rect: vec4<f32>;
2223
};
2324

2425
struct VertexOutput {
@@ -46,11 +47,11 @@ fn vertex(
4647
vec2<f32>( 0.5, 0.5), // top right
4748
vec2<f32>(-0.5, 0.5), // top left
4849
);
49-
var unit_quad_uv: array<vec2<f32>, 4> = array<vec2<f32>, 4>(
50-
vec2<f32>(1.0, 1.0), // bottom right
51-
vec2<f32>(0.0, 1.0), // bottom left
52-
vec2<f32>(1.0, 0.0), // top right
53-
vec2<f32>(0.0, 0.0), // top left
50+
var quad_uv: array<vec2<f32>, 4> = array<vec2<f32>, 4>(
51+
vec2<f32>(instance.uv_rect[2], instance.uv_rect[3]), // bottom right
52+
vec2<f32>(instance.uv_rect[0], instance.uv_rect[3]), // bottom left
53+
vec2<f32>(instance.uv_rect[2], instance.uv_rect[1]), // top right
54+
vec2<f32>(instance.uv_rect[0], instance.uv_rect[1]), // top left
5455
);
5556
// Scale the vertices of the unit square
5657
let scaled_position = unit_quad_pos[vertex.index] * instance.size;
@@ -59,7 +60,7 @@ fn vertex(
5960
var out: VertexOutput;
6061
out.clip_position = clip_position;
6162
out.color = instance.color;
62-
out.uv = unit_quad_uv[vertex.index];
63+
out.uv = quad_uv[vertex.index];
6364
return out;
6465
}
6566

pipelined/bevy_ui2/src/widget/text.rs

+4-58
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,15 @@
1-
use crate::{CalculatedSize, Style, UiNode, Val};
1+
use crate::{CalculatedSize, Style, Val};
22
use bevy_asset::Assets;
33
use bevy_ecs::{
44
entity::Entity,
55
prelude::QueryState,
6-
query::{Changed, Or, With, Without},
7-
system::{Local, Query, QuerySet, Res, ResMut},
6+
query::{Changed, Or, With},
7+
system::{Local, QuerySet, Res, ResMut},
88
};
99
use bevy_math::Size;
1010
use bevy_render2::texture::Image;
1111
use bevy_sprite2::TextureAtlas;
12-
// use bevy_render::{
13-
// draw::{Draw, DrawContext, Drawable, OutsideFrustum},
14-
// mesh::Mesh,
15-
// prelude::{Msaa, Visible},
16-
// renderer::RenderResourceBindings,
17-
// texture::Texture,
18-
// };
19-
// use bevy_sprite::{TextureAtlas, QUAD_HANDLE};
20-
use bevy_text2::{DefaultTextPipeline, /*DrawableText,*/ Font, FontAtlasSet, Text, TextError};
21-
use bevy_transform::prelude::GlobalTransform;
12+
use bevy_text2::{DefaultTextPipeline, Font, FontAtlasSet, Text, TextError};
2213
use bevy_window::Windows;
2314

2415
#[derive(Debug, Default)]
@@ -141,48 +132,3 @@ pub fn text_system(
141132

142133
queued_text.entities = new_queue;
143134
}
144-
/*
145-
#[allow(clippy::too_many_arguments, clippy::type_complexity)]
146-
pub fn draw_text_system(
147-
mut context: DrawContext,
148-
msaa: Res<Msaa>,
149-
windows: Res<Windows>,
150-
meshes: Res<Assets<Mesh>>,
151-
mut render_resource_bindings: ResMut<RenderResourceBindings>,
152-
text_pipeline: Res<DefaultTextPipeline>,
153-
mut query: Query<
154-
(Entity, &mut Draw, &Visible, &Text, &Node, &GlobalTransform),
155-
Without<OutsideFrustum>,
156-
>,
157-
) {
158-
let scale_factor = if let Some(window) = windows.get_primary() {
159-
window.scale_factor()
160-
} else {
161-
1.
162-
};
163-
164-
let font_quad = meshes.get(&QUAD_HANDLE).unwrap();
165-
let vertex_buffer_layout = font_quad.get_vertex_buffer_layout();
166-
167-
for (entity, mut draw, visible, text, node, global_transform) in query.iter_mut() {
168-
if !visible.is_visible {
169-
continue;
170-
}
171-
172-
if let Some(text_glyphs) = text_pipeline.get_glyphs(&entity) {
173-
let mut drawable_text = DrawableText {
174-
render_resource_bindings: &mut render_resource_bindings,
175-
global_transform: *global_transform,
176-
scale_factor: scale_factor as f32,
177-
msaa: &msaa,
178-
text_glyphs: &text_glyphs.glyphs,
179-
font_quad_vertex_layout: &vertex_buffer_layout,
180-
sections: &text.sections,
181-
alignment_offset: (node.size / -2.0).extend(0.0),
182-
};
183-
184-
drawable_text.draw(&mut draw, &mut context).unwrap();
185-
}
186-
}
187-
}
188-
*/

0 commit comments

Comments
 (0)