public void Draw() { var textGroupedByColor = textToDraw.GroupBy(t => t.Color); // Render text sets by color foreach (var colorGroup in textGroupedByColor) { commandList.SetPipeline(glyphPipeline); commandList.SetGraphicsResourceSet(0, textPropertiesSet); commandList.SetFramebuffer(glyphTextureFramebuffer); commandList.ClearColorTarget(0, new RgbaFloat(0, 0, 0, 0)); var updateRect = new BoundingRectangle(); updateRect.Reset(); foreach (var drawable in colorGroup) { var advanceX = 0f; for (var i = 0; i < drawable.Glyphs.Length; i++) { var glyphAdvanceX = drawable.Glyphs[i].AdvanceX; // Transform letter spacing from 1 based to 0 based glyphAdvanceX += (drawable.LetterSpacing - 1) * Font.FontSizeInPixels; var glyphCoordsInPixels = new Vector2(advanceX, 0) + drawable.Position; DrawGlyph(commandList, drawable.Glyphs[i].Vertices, glyphCoordsInPixels); advanceX += glyphAdvanceX; } updateRect.Include(drawable.Position.X * aspectWidth / 2f, drawable.Position.Y * aspectHeight / 2f); updateRect.Include((drawable.Position.X + advanceX) * aspectWidth / 2f, (drawable.Position.Y + Font.FontSizeInPixels) * aspectHeight / 2f); } const float paddingPixels = 1; updateRect.Include(updateRect.StartX - (paddingPixels * aspectWidth / 2f), updateRect.StartY - (paddingPixels * aspectHeight / 2f)); updateRect.Include(updateRect.EndX + (paddingPixels * aspectWidth / 2f), updateRect.EndY + (paddingPixels * aspectHeight / 2f)); // 2nd pass, render everything to the framebuffer DrawOutput(commandList, new Color(0, 0, 0, 0), false, updateRect.ToVector4()); // We need to do a second pass if we would like a color other than black text if (colorGroup.Key != new Color(0, 0, 0, 1)) { DrawOutput(commandList, colorGroup.Key, true, updateRect.ToVector4()); } } }