diff --git a/OpenRA.Game/Renderer.cs b/OpenRA.Game/Renderer.cs index c733216387..db4058ee6b 100644 --- a/OpenRA.Game/Renderer.cs +++ b/OpenRA.Game/Renderer.cs @@ -377,6 +377,24 @@ namespace OpenRA Context.ClearDepthBuffer(); } + public void EnableAntialiasingFilter() + { + if (renderType != RenderType.UI) + throw new InvalidOperationException("EndFrame called with renderType = {0}, expected RenderType.UI.".F(renderType)); + + Flush(); + SpriteRenderer.SetAntialiasingPixelsPerTexel(Window.WindowScale); + } + + public void DisableAntialiasingFilter() + { + if (renderType != RenderType.UI) + throw new InvalidOperationException("EndFrame called with renderType = {0}, expected RenderType.UI.".F(renderType)); + + Flush(); + SpriteRenderer.SetAntialiasingPixelsPerTexel(0); + } + public void GrabWindowMouseFocus() { Window.GrabWindowMouseFocus(); diff --git a/OpenRA.Mods.Common/Widgets/ActorPreviewWidget.cs b/OpenRA.Mods.Common/Widgets/ActorPreviewWidget.cs index 0f6a2723f4..06108135d1 100644 --- a/OpenRA.Mods.Common/Widgets/ActorPreviewWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ActorPreviewWidget.cs @@ -74,8 +74,10 @@ namespace OpenRA.Mods.Common.Widgets public override void Draw() { + Game.Renderer.EnableAntialiasingFilter(); foreach (var r in renderables) r.Render(worldRenderer); + Game.Renderer.DisableAntialiasingFilter(); } public override void Tick() diff --git a/OpenRA.Mods.Common/Widgets/ObserverProductionIconsWidget.cs b/OpenRA.Mods.Common/Widgets/ObserverProductionIconsWidget.cs index 415a9347f3..fbbbfa850c 100644 --- a/OpenRA.Mods.Common/Widgets/ObserverProductionIconsWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ObserverProductionIconsWidget.cs @@ -116,10 +116,17 @@ namespace OpenRA.Mods.Common.Widgets Bounds.Width = currentItemsByItem.Count * (IconWidth + IconSpacing); + Game.Renderer.EnableAntialiasingFilter(); + var queueCol = 0; foreach (var currentItems in currentItemsByItem) { - var current = currentItems.OrderBy(pi => pi.Done ? 0 : (pi.Paused ? 2 : 1)).ThenBy(q => q.RemainingTimeActual).First(); + var queued = currentItems + .OrderBy(pi => pi.Done ? 0 : (pi.Paused ? 2 : 1)) + .ThenBy(q => q.RemainingTimeActual) + .ToList(); + + var current = queued.First(); var queue = current.Queue; var faction = queue.Actor.Owner.Faction.InternalName; @@ -135,18 +142,26 @@ namespace OpenRA.Mods.Common.Widgets var topLeftOffset = new float2(queueCol * (IconWidth + IconSpacing), 0); var iconTopLeft = RenderOrigin + topLeftOffset; - var centerPosition = iconTopLeft; + var centerPosition = iconTopLeft + 0.5f * iconSize; - WidgetUtils.DrawSHPCentered(icon.Image, centerPosition + 0.5f * iconSize, worldRenderer.Palette(bi.IconPalette), 0.5f); + WidgetUtils.DrawSHPCentered(icon.Image, centerPosition, worldRenderer.Palette(bi.IconPalette), 0.5f); - productionIcons.Add(new ProductionIcon { Actor = actor, ProductionQueue = current.Queue }); - productionIconsBounds.Add(new Rectangle((int)iconTopLeft.X, (int)iconTopLeft.Y, (int)iconSize.X, (int)iconSize.Y)); + var rect = new Rectangle((int)iconTopLeft.X, (int)iconTopLeft.Y, (int)iconSize.X, (int)iconSize.Y); + productionIcons.Add(new ProductionIcon + { + Actor = actor, + Pos = new float2(rect.Location), + Queued = queued, + ProductionQueue = current.Queue + }); + + productionIconsBounds.Add(rect); var pio = queue.Actor.Owner.PlayerActor.TraitsImplementing() .FirstOrDefault(p => p.IsOverlayActive(actor)); if (pio != null) - WidgetUtils.DrawSHPCentered(pio.Sprite, centerPosition + 0.5f * iconSize + pio.Offset(iconSize), + WidgetUtils.DrawSHPCentered(pio.Sprite, centerPosition + pio.Offset(iconSize), worldRenderer.Palette(pio.Palette), 0.5f); var clock = clocks[queue]; @@ -154,24 +169,30 @@ namespace OpenRA.Mods.Common.Widgets (current.TotalTime - current.RemainingTime) * (clock.CurrentSequence.Length - 1) / current.TotalTime); clock.Tick(); - WidgetUtils.DrawSHPCentered(clock.Image, centerPosition + 0.5f * iconSize, worldRenderer.Palette(ClockPalette), 0.5f); - - var tiny = Game.Renderer.Fonts["Tiny"]; - var text = GetOverlayForItem(current, timestep); - tiny.DrawTextWithContrast(text, - centerPosition + new float2(16, 12) - new float2(tiny.Measure(text).X / 2, 0), - Color.White, Color.Black, 1); - - if (currentItems.Count() > 1) - { - var bold = Game.Renderer.Fonts["Small"]; - text = currentItems.Count().ToString(); - bold.DrawTextWithContrast(text, centerPosition + new float2(16, 0) - new float2(bold.Measure(text).X / 2, 0), - Color.White, Color.Black, 1); - } + WidgetUtils.DrawSHPCentered(clock.Image, centerPosition, worldRenderer.Palette(ClockPalette), 0.5f); queueCol++; } + + Game.Renderer.DisableAntialiasingFilter(); + + var tiny = Game.Renderer.Fonts["Tiny"]; + var bold = Game.Renderer.Fonts["Small"]; + foreach (var icon in productionIcons) + { + var current = icon.Queued.First(); + var text = GetOverlayForItem(current, timestep); + tiny.DrawTextWithContrast(text, + icon.Pos + new float2(16, 12) - new float2(tiny.Measure(text).X / 2, 0), + Color.White, Color.Black, 1); + + if (icon.Queued.Count > 1) + { + text = icon.Queued.Count.ToString(); + bold.DrawTextWithContrast(text, icon.Pos + new float2(16, 0) - new float2(bold.Measure(text).X / 2, 0), + Color.White, Color.Black, 1); + } + } } static string GetOverlayForItem(ProductionItem item, int timestep) diff --git a/OpenRA.Mods.Common/Widgets/ObserverSupportPowerIconsWidget.cs b/OpenRA.Mods.Common/Widgets/ObserverSupportPowerIconsWidget.cs index 659f086a1d..15d635a3b0 100644 --- a/OpenRA.Mods.Common/Widgets/ObserverSupportPowerIconsWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ObserverSupportPowerIconsWidget.cs @@ -115,6 +115,8 @@ namespace OpenRA.Mods.Common.Widgets Bounds.Width = powers.Count() * (IconWidth + IconSpacing); + Game.Renderer.EnableAntialiasingFilter(); + var iconSize = new float2(IconWidth, IconHeight); foreach (var power in powers) { @@ -125,7 +127,7 @@ namespace OpenRA.Mods.Common.Widgets icon.Play(item.Info.Icon); var location = new float2(RenderBounds.Location) + new float2(power.i * (IconWidth + IconSpacing), 0); - supportPowerIconsIcons.Add(new SupportPowersWidget.SupportPowerIcon { Power = item }); + supportPowerIconsIcons.Add(new SupportPowersWidget.SupportPowerIcon { Power = item, Pos = location }); supportPowerIconsBounds.Add(new Rectangle((int)location.X, (int)location.Y, (int)iconSize.X, (int)iconSize.Y)); WidgetUtils.DrawSHPCentered(icon.Image, location + 0.5f * iconSize, worldRenderer.Palette(item.Info.IconPalette), 0.5f); @@ -136,11 +138,16 @@ namespace OpenRA.Mods.Common.Widgets * (clock.CurrentSequence.Length - 1) / item.TotalTicks)); clock.Tick(); WidgetUtils.DrawSHPCentered(clock.Image, location + 0.5f * iconSize, worldRenderer.Palette(ClockPalette), 0.5f); + } - var tiny = Game.Renderer.Fonts["Tiny"]; - var text = GetOverlayForItem(item, timestep); + Game.Renderer.DisableAntialiasingFilter(); + + var tiny = Game.Renderer.Fonts["Tiny"]; + foreach (var icon in supportPowerIconsIcons) + { + var text = GetOverlayForItem(icon.Power, timestep); tiny.DrawTextWithContrast(text, - location + new float2(16, 12) - new float2(tiny.Measure(text).X / 2, 0), + icon.Pos + new float2(16, 12) - new float2(tiny.Measure(text).X / 2, 0), Color.White, Color.Black, 1); } } diff --git a/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs b/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs index 6ac3ae297c..a0fa5d633b 100644 --- a/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs @@ -453,6 +453,7 @@ namespace OpenRA.Mods.Common.Widgets var pios = currentQueue.Actor.Owner.PlayerActor.TraitsImplementing(); // Icons + Game.Renderer.EnableAntialiasingFilter(); foreach (var icon in icons.Values) { WidgetUtils.DrawSHPCentered(icon.Sprite, icon.Pos + iconOffset, icon.Palette); @@ -477,6 +478,8 @@ namespace OpenRA.Mods.Common.Widgets WidgetUtils.DrawSHPCentered(cantBuild.Image, icon.Pos + iconOffset, icon.IconDarkenPalette); } + Game.Renderer.DisableAntialiasingFilter(); + // Overlays foreach (var icon in icons.Values) { diff --git a/OpenRA.Mods.Common/Widgets/SpriteWidget.cs b/OpenRA.Mods.Common/Widgets/SpriteWidget.cs index 4159481aea..5d5a191d96 100644 --- a/OpenRA.Mods.Common/Widgets/SpriteWidget.cs +++ b/OpenRA.Mods.Common/Widgets/SpriteWidget.cs @@ -78,7 +78,9 @@ namespace OpenRA.Mods.Common.Widgets } var size = new float2(sprite.Size.X * scale, sprite.Size.Y * scale); + Game.Renderer.EnableAntialiasingFilter(); Game.Renderer.SpriteRenderer.DrawSprite(sprite, RenderOrigin + offset, pr, size); + Game.Renderer.DisableAntialiasingFilter(); } } } diff --git a/OpenRA.Mods.Common/Widgets/SupportPowersWidget.cs b/OpenRA.Mods.Common/Widgets/SupportPowersWidget.cs index 5806860574..40fe03032a 100644 --- a/OpenRA.Mods.Common/Widgets/SupportPowersWidget.cs +++ b/OpenRA.Mods.Common/Widgets/SupportPowersWidget.cs @@ -198,6 +198,7 @@ namespace OpenRA.Mods.Common.Widgets timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0, worldRenderer.World.Timestep)) / 2; // Icons + Game.Renderer.EnableAntialiasingFilter(); foreach (var p in icons.Values) { WidgetUtils.DrawSHPCentered(p.Sprite, p.Pos + iconOffset, p.Palette); @@ -212,6 +213,8 @@ namespace OpenRA.Mods.Common.Widgets WidgetUtils.DrawSHPCentered(clock.Image, p.Pos + iconOffset, p.IconClockPalette); } + Game.Renderer.DisableAntialiasingFilter(); + // Overlay foreach (var p in icons.Values) {