FosterFramework / Foster

A small C# game framework
MIT License
422 stars 37 forks source link

Cannot render uppercase letters after commit 647dd369 #90

Closed tapir2342 closed 2 months ago

tapir2342 commented 2 months ago

Hi! Since the changes introduced in 647dd369, I can no longer render uppercase letters.

For example, when rendering "FoStEr", I get this:

Screenshot 2024-06-07 at 21 16 10

The kerning seems to be correct, but the uppercase letters are just not rendered. I have looked through the code (especially the changes introduced in the above commit), but I don't know enough about text rendering to figure out what the problem is. This is with Sprite.DynamicBlittingEnabled set to true. If I set it to false, I don't see any text being rendered.

I'm using it on macOS Sonoma (14.4.1) at the moment. I haven't gotten to try it on another OSes yet.

tapir2342 commented 2 months ago

Right after sending this off I realized that it is obviously rendering the first "F". However, when I debugged this, I always used "ULTRAMASSIVE" instead (with the same alternating upper/lowercase letters). Which emits:

Screenshot 2024-06-07 at 21 23 26

So there the first letter doesn't show up.

NoelFB commented 2 months ago

Interesting ... I am out today but I'll investigate this tonight! What font are you using? I'll test with the same parameters as my local tests were working OK when I pushed the changes.

NoelFB commented 2 months ago

Also yeah if Dynamic Blitting is false it simply will not draw anything unless you call PrepareCharacters with immediate true first, so that it actually blits the characters required for drawing.

Edit: I'm probably in favor of tweaking this API a bit to make that a bit more clear (or still rendering the required characters by halting the main thread to prepare them)

tapir2342 commented 2 months ago

Hi Noel, I appreciate you looking into this! I'm using Inter Tight (the "Black" variant, filename: InterTight-Black.ttf) in these examples. Please note that it's not an urgent problem for me.

NoelFB commented 2 months ago

Alright so I'm not able to reproduce this on my end with the same font, but I do have some thoughts... If you're only rendering this text one time, the characters may not have had time to be rendered that frame and thus wouldn't appear. In all my tests, I draw the text every frame so the characters seem to appear immediately.

I have a few thoughts. I think basically the API needs to change to some kind of enum, and default to a mode that requires the characters to be rendered immediately before they are presented.

If doing this below doesn't work, then I think there is potentially some other bug that for some reason isn't happening on my end:

var font = new SpriteFont("InterTight-Black.ttf", 64);
font.DynamicBlittingEnabled = false;
font.PrepareCharacters(SpriteFont.Ascii, true);

However if that does fix the issue, then I think it's the problem I described above.

NoelFB commented 2 months ago

I've actually changed the API a little bit to use an enum now. It defaults to an immediate mode (forcing characters to be fully ready before rendering occurs), with a Streaming mode as another option (prepare characters in a background thread which means they may not necessarily be ready when rendering). Curious if this solves the issues for you!

tapir2342 commented 2 months ago

Hi Noel, it works for me now! Thanks a lot for tweaking the API!

This is not relevant for this ticket, but I think I will try figure out what I did wrong initially. Because my assumption was that I might not see all characters immediately (on frame 1), but all of them should eventually show up. I.e., just trying to understand what was going on and why I hadn't been able to figure it out.

NoelFB commented 2 months ago

Yeah, in the original version they should have all eventually shown up. There may have been something wrong with the code before I refactored it to an enum...

I'll close this for now but if you find anything relevant feel free to open another issue or reply again!