fix corrupted text bug

This commit is contained in:
griffi-gh 2024-03-06 21:14:40 +01:00
parent cd6d421909
commit d4151e6c76
2 changed files with 38 additions and 0 deletions

View file

@ -97,6 +97,32 @@ impl UiDrawCall {
pub(crate) fn build(draw_commands: &UiDrawCommandList, atlas: &mut TextureAtlasManager, text_renderer: &mut TextRenderer) -> Self {
let mut trans_stack = Vec::new();
let mut draw_call = UiDrawCall::default();
//HACK: atlas may get resized while creating new glyphs,
//which invalidates all uvs, causing corrupted-looking texture
//so we need to pregenerate font textures before generating any vertices
//we are doing *a lot* of double work here, but it's the easiest way to avoid the issue
for comamnd in &draw_commands.commands {
if let UiDrawCommand::Text { text, font: font_handle, size, .. } = comamnd {
let mut layout = Layout::new(CoordinateSystem::PositiveYDown);
layout.append(
&[text_renderer.internal_font(*font_handle)],
&TextStyle::new(text, *size as f32, 0)
);
let glyphs = layout.glyphs();
for layout_glyph in glyphs {
if !layout_glyph.char_data.rasterize() { continue }
text_renderer.glyph(atlas, *font_handle, layout_glyph.parent, layout_glyph.key.px as u8);
}
}
}
//note to future self:
//RESIZING OR ADDING STUFF TO ATLAS AFTER THIS POINT IS A BIG NO-NO,
//DON'T DO IT EVER AGAIN UNLESS YOU WANT TO SPEND HOURS DEBUGGING
atlas.lock_atlas = true;
for command in &draw_commands.commands {
match command {
UiDrawCommand::PushTransform(trans) => {
@ -328,10 +354,14 @@ impl UiDrawCall {
}
}
}
atlas.lock_atlas = false;
#[cfg(feature = "pixel_perfect")]
draw_call.vertices.iter_mut().for_each(|v| {
v.position = v.position.round()
});
draw_call
}
}

View file

@ -59,6 +59,10 @@ pub(crate) struct TextureAtlasManager {
/// True if the atlas has been modified in a way which requires a texture reupload
/// since the beginning of the current frame
modified: bool,
/// If true, attempting to modify the atlas in a way which invalidates UVs will cause a panic\
/// Used internally to ensure that the UVs do not become invalidated mid-render
pub(crate) lock_atlas: bool,
}
impl TextureAtlasManager {
@ -73,11 +77,15 @@ impl TextureAtlasManager {
allocations: HashMap::default(),
remove_queue: Vec::new(),
modified: true,
lock_atlas: false,
}
}
/// Resize the texture atlas to the new size in-place, preserving the existing data
pub fn resize(&mut self, new_size: UVec2) {
if self.lock_atlas {
panic!("Attempted to resize the texture atlas while the atlas is locked");
}
log::trace!("resizing texture atlas to {:?}", new_size);
if self.size == new_size {
log::warn!("Texture atlas is already the requested size");