17cupsofcoffee / tetra

🎮 A simple 2D game framework written in Rust
MIT License
920 stars 63 forks source link

Changing text using set_content() has a chance to make glitching text. #225

Closed Im-Oab closed 3 years ago

Im-Oab commented 3 years ago

Summary: continuous changing text using set_content() has a chance to cause glitching on display text. (acttached images)

Steps to reproduce:

Expected behavior:

Additional info:

tetra 0.5.7, OSX Catalina

Screenshots: // This happen after call set_content() several times. Screen Shot 2021-01-24 at 1 57 42 pm

// This text call set_content() once but show it later. Between setup and the time it draws on screen. The game call set_content() on another text object several times. Screen Shot 2021-01-24 at 2 06 09 pm

Codes: `

pub fn update(&mut self, ctx: &mut Context) {
    let game_system = crate::GAME_SYSTEM.lock().unwrap();
    self.target_score = game_system.score();

    if self.current_score < self.target_score {
        self.current_score +=
            1 + ((self.target_score - self.current_score) as f64 * 0.25).ceil() as u64;
        self.current_score = self.current_score.min(self.target_score);

        self.score_text
            .set_content(format!("{:0>9}", self.current_score));
    }
}

pub fn draw(&self, ctx: &mut Context) {
    let position = match self.score_text.get_bounds(ctx) {
        Some(rect) => ((crate::SCREEN_WIDTH - rect.width) / 2.0, 32.0),
        None => (32.0, 23.0),
    };

    {
        let params = DrawParams::new()
            .position(Vec2::new(position.0 - 1.0, position.1 - 1.0))
            .color(Color::WHITE);

        graphics::draw(ctx, &self.score_text, params);
    }

    {
        let params = DrawParams::new()
            .position(Vec2::new(position.0+2.0, position.1+2.0))
            .color(Color::rgba8(255, 20, 20, 255));

        graphics::draw(ctx, &self.score_text, params);
    }

    {
        let params = DrawParams::new()
            .position(Vec2::new(position.0, position.1))
            .color(Color::BLACK);

        graphics::draw(ctx, &self.score_text, params);
    }
}

`

17cupsofcoffee commented 3 years ago

That's very strange 🤔

The artifacts you're seeing look like they could be a result of stuff overlapping/bleeding into eachother in the font atlas, but that's not meant to be possible - everything gets laid out with a 1px border to avoid that:

image

Which font are you using? If it's a free one, I can possibly try to replicate the issue on my end.

Im-Oab commented 3 years ago

I use D-DINCondensed font.

https://www.1001fonts.com/d-din-font.html

17cupsofcoffee commented 3 years ago

I've not been able to replicate the issue yet, but I did find a small problem with the font atlas code (it wasn't including the padding I previously mentioned after a texture resize took place). I've pushed a fix for that issue to the main branch - could you try running your code with that and see if it fixes your problem (or at least improves it)?

[dependencies]
tetra = { git = "https://github.com/17cupsofcoffee/tetra", branch = "main" }

If not, some other questions that might help me replicate the issue:

Im-Oab commented 3 years ago

It's not fixed when I changed to the main branch but when I use ceil() with the position that passes to DrawParam. This issue disappears.

Thank you. :)

17cupsofcoffee commented 3 years ago

No problem! The text rendering code does some subpixel/anti-aliased rendering stuff which can look a bit weird if you draw off the pixel grid, but I've never seen it cause artifacts like this before.