Skip to content

Commit 5d254d1

Browse files
committed
Added TextLabel single-drawcall support for non-sdf fonts
1 parent 7abc4ac commit 5d254d1

2 files changed

Lines changed: 98 additions & 4 deletions

File tree

Assets/Scripts/Game/UserInterface/DaggerfallFont.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,16 @@ public SDFFontInfo SDFInfo
135135
get { return sdfFontInfo.Value; }
136136
}
137137

138+
public Texture2D AtlasTexture
139+
{
140+
get { return atlasTexture; }
141+
}
142+
143+
public Rect[] AtlasRects
144+
{
145+
get { return atlasRects; }
146+
}
147+
138148
#endregion
139149

140150
#region Constructors

Assets/Scripts/Game/UserInterface/TextLabel.cs

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public override void Draw()
231231
DrawLabel();
232232
}
233233

234-
void DrawLabelSingleCall()
234+
void DrawLabelSingleCallSDF()
235235
{
236236
if (glyphLayout.Count == 0)
237237
return;
@@ -306,17 +306,101 @@ void DrawLabelSingleCall()
306306
GL.PopMatrix();
307307
}
308308

309+
void DrawLabelSingleCallClassic()
310+
{
311+
if (glyphLayout.Count == 0)
312+
return;
313+
314+
Material mat = DaggerfallUI.Instance.PixelFontMaterial;
315+
316+
Vector4 scissorRect = (UseRestrictedRenderArea) ? GetRestrictedRenderScissorRect() : new Vector4(0, 1, 0, 1);
317+
mat.SetVector("_ScissorRect", scissorRect);
318+
mat.SetTexture("_MainTex", font.AtlasTexture);
319+
mat.SetColor("_Color", textColor);
320+
mat.SetColor(UIShaderParam._Color, textColor);
321+
322+
mat.SetPass(0);
323+
324+
// 2) Inverted pixel matrix: y=0 at top
325+
GL.PushMatrix();
326+
GL.LoadPixelMatrix(0, Screen.width, Screen.height, 0);
327+
328+
// 3) Precompute constants
329+
float scaleX = LocalScale.x * textScale;
330+
float scaleY = LocalScale.y * textScale;
331+
// For classic fonts, height is usually uniform based on font.GlyphHeight
332+
float h = Mathf.Round(font.GlyphHeight * scaleY); // Rounded height for all glyphs
333+
334+
// 4) One GL.Begin/End for everything
335+
GL.Begin(GL.QUADS);
336+
GL.Color(textColor); // Set current vertex color for all subsequent vertices
337+
338+
foreach (var g in glyphLayout)
339+
{
340+
// Skip spaces
341+
if (g.code == ' ')
342+
continue;
343+
344+
// Get glyph index (handle potential out-of-range)
345+
int glyphIndex = g.code - font.AsciiStart;
346+
if (glyphIndex < 0 || glyphIndex >= font.AtlasRects.Length)
347+
continue; // Skip if code is outside the font's range
348+
349+
// Get UV rectangle from the font's atlas map
350+
Rect uvRect = font.AtlasRects[glyphIndex];
351+
352+
// Calculate width based on layout data (g.width)
353+
float w = Mathf.Round(g.width * scaleX);
354+
355+
// Compute top-left screen position
356+
// Uses g.x, g.y from layout directly, similar to original multi-call DrawLabel
357+
float x = Rectangle.x
358+
+ (g.x + HorzPixelScrollOffset) * scaleX; // Include horizontal scroll
359+
360+
float y = Rectangle.y
361+
+ g.y * scaleY; // g.y seems to be the top offset already
362+
363+
// Pixel-perfect rounding for position
364+
x = Mathf.Round(x);
365+
y = Mathf.Round(y);
366+
367+
// Get UVs and flip V because we inverted the pixel matrix
368+
float u0 = uvRect.xMin, u1 = uvRect.xMax;
369+
float v0 = uvRect.yMax, v1 = uvRect.yMin; // Flipped V
370+
371+
// Emit the quad (TL, TR, BR, BL)
372+
GL.TexCoord2(u0, v0); GL.Vertex3(x, y, 0);
373+
GL.TexCoord2(u1, v0); GL.Vertex3(x + w, y, 0);
374+
GL.TexCoord2(u1, v1); GL.Vertex3(x + w, y + h, 0);
375+
GL.TexCoord2(u0, v1); GL.Vertex3(x, y + h, 0);
376+
}
377+
GL.End();
378+
379+
// 5) Clean up
380+
GL.PopMatrix();
381+
}
382+
309383
void DrawLabel()
310384
{
311385
// Exit if no layout
312386
if (glyphLayout.Count == 0)
313387
return;
314388

315-
if(font.IsSDFCapable){
316-
DrawLabelSingleCall();
317-
return;
389+
try{
390+
if(font.IsSDFCapable){
391+
DrawLabelSingleCallSDF();
392+
}
393+
else{
394+
DrawLabelSingleCallClassic();
395+
}
396+
} catch (Exception e){
397+
Debug.LogError(e);
398+
DrawLabelMultiCall();
318399
}
319400

401+
}
402+
void DrawLabelMultiCall()
403+
{
320404
// Set render area
321405
Material material = font.GetMaterial();
322406
Vector4 scissorRect = (UseRestrictedRenderArea) ? GetRestrictedRenderScissorRect() : new Vector4(0, 1, 0, 1);

0 commit comments

Comments
 (0)