Skip to content
Permalink
Browse files

[Fonts] Dynamic fonts: use virtual resolution (otherwise real size ch…

…anges on every camera move and requests new character, esp. if UI is in 3D)
  • Loading branch information
xen2 committed Oct 22, 2019
1 parent eafa92f commit 22271fb90375a28740e99b3900b5325e4934e6c4
@@ -76,6 +76,7 @@ public void UploadCharacterBitmap(CommandList commandList, CharacterSpecificatio
if (!packer.Insert(targetSize.X, targetSize.Y, ref character.Glyph.Subrect))
{
// memory is too fragmented in order to place the new character -> clear all the characters and restart.
// TODO: This is invalid, we might delete character from current frame!
ClearCache();
if (!packer.Insert(targetSize.X, targetSize.Y, ref character.Glyph.Subrect))
throw new InvalidOperationException("The rendered character is too big for the cache texture");
@@ -100,16 +100,20 @@ public override bool IsCharPresent(char c)
protected override Glyph GetGlyph(CommandList commandList, char character, ref Vector2 fontSize, bool uploadGpuResources, out Vector2 fixScaling)
{
// Add a safe guard to prevent the system to generate characters too big for the dynamic font cache texture
fontSize.X = Math.Min(fontSize.X, 1024);
fontSize.Y = Math.Min(fontSize.Y, 1024);
fontSize.X = Math.Min(fontSize.X, 256);
fontSize.Y = Math.Min(fontSize.Y, 256);

// get the character data associated to the provided character and size
var characterData = GetOrCreateCharacterData(fontSize, character);

// generate the bitmap if it does not exist
if (characterData.Bitmap == null)
{
FontManager.GenerateBitmap(characterData, false);

// TODO: try to find a fallback from different size in the meantime (currently character disappear)
}

// upload the character to the GPU font texture and create the glyph if does not exists
if (uploadGpuResources && characterData.Bitmap != null && !characterData.IsBitmapUploaded)
FontCacheManager.UploadCharacterBitmap(commandList, characterData);
@@ -442,20 +442,28 @@ internal void DrawString(SpriteFont font, string text, ref SpriteFont.InternalUI
// transform the world matrix into the world view project matrix
Matrix.MultiplyTo(ref worldMatrix, ref viewProjectionMatrix, out drawCommand.Matrix);

// do not snap static fonts when real/virtual resolution does not match.
if (font.FontType == SpriteFontType.SDF)
{
drawCommand.SnapText = false;
float scaling = drawCommand.RequestedFontSize / font.Size;
drawCommand.RealVirtualResolutionRatio = 1 / new Vector2(scaling, scaling);
}
else if ((font.FontType == SpriteFontType.Static))
if (font.FontType == SpriteFontType.Static)
{
if ((drawCommand.RealVirtualResolutionRatio.X != 1 || drawCommand.RealVirtualResolutionRatio.Y != 1))
drawCommand.SnapText = false; // we don't want snapping of the resolution of the screen does not match virtual resolution. (character alignment problems)

drawCommand.RealVirtualResolutionRatio = Vector2.One; // ensure that static font are not scaled internally
}
if (font.FontType == SpriteFontType.Dynamic || font.FontType == SpriteFontType.Static)
{
// do not snap static fonts when real/virtual resolution does not match.
if (drawCommand.RealVirtualResolutionRatio.X != 1 || drawCommand.RealVirtualResolutionRatio.Y != 1)
drawCommand.SnapText = false; // we don't want snapping of the resolution of the screen does not match virtual resolution. (character alignment problems)
}
if (font.FontType == SpriteFontType.Dynamic)
{
// Dynamic: use virtual resolution (otherwise requested size might change on every camera move, esp. if UI is in 3D)
// TODO: some step function to have LOD without regenerating on every small change?
drawCommand.RealVirtualResolutionRatio = Vector2.One;
}

// snap draw start position to prevent characters to be drawn in between two pixels
if (drawCommand.SnapText)

0 comments on commit 22271fb

Please sign in to comment.
You can’t perform that action at this time.