Set world framebuffer size based on minimum zoom.

This avoids reallocating buffers each time the player changes zoom level.
This commit is contained in:
Paul Chote
2021-05-15 13:45:09 +01:00
committed by reaperrr
parent 0735345674
commit 0d4b81fe6f
4 changed files with 38 additions and 19 deletions

View File

@@ -250,6 +250,9 @@ namespace OpenRA.Graphics
else
Zoom = Zoom.Clamp(minZoom, maxZoom);
var maxSize = (1f / (unlockMinZoom ? unlockedMinZoom : minZoom) * new float2(Game.Renderer.NativeResolution));
Game.Renderer.SetMaximumViewportSize(new Size((int)maxSize.X, (int)maxSize.Y));
foreach (var t in worldRenderer.World.WorldActor.TraitsImplementing<INotifyViewportZoomExtentsChanged>())
t.ViewportZoomExtentsChanged(minZoom, maxZoom);
}

View File

@@ -50,8 +50,11 @@ namespace OpenRA
Sprite screenSprite;
IFrameBuffer worldBuffer;
Sheet worldSheet;
Sprite worldSprite;
public Size WorldFrameBufferSize => worldSheet.Size;
SheetBuilder fontSheetBuilder;
readonly IPlatform platform;
@@ -59,7 +62,6 @@ namespace OpenRA
Size lastBufferSize = new Size(-1, -1);
Size lastWorldBufferSize = new Size(-1, -1);
Rectangle lastWorldViewport = Rectangle.Empty;
ITexture currentPaletteTexture;
IBatchRenderer currentBatchRenderer;
@@ -178,14 +180,9 @@ namespace OpenRA
}
}
public void BeginWorld(Rectangle worldViewport)
public void SetMaximumViewportSize(Size size)
{
if (renderType != RenderType.None)
throw new InvalidOperationException($"BeginWorld called with renderType = {renderType}, expected RenderType.None.");
BeginFrame();
var worldBufferSize = worldViewport.Size.NextPowerOf2();
var worldBufferSize = size.NextPowerOf2();
if (worldSprite == null || worldSprite.Sheet.Size != worldBufferSize)
{
worldBuffer?.Dispose();
@@ -195,24 +192,36 @@ namespace OpenRA
// Pixel art scaling mode is a customized bilinear sampling
worldBuffer.Texture.ScaleFilter = TextureScaleFilter.Linear;
worldSheet = new Sheet(SheetType.BGRA, worldBuffer.Texture);
// Invalidate cached state to force a shader update
lastWorldViewport = Rectangle.Empty;
worldSprite = null;
}
}
if (worldSprite == null || worldViewport.Size != worldSprite.Bounds.Size)
public void BeginWorld(Rectangle worldViewport)
{
var worldSheet = new Sheet(SheetType.BGRA, worldBuffer.Texture);
if (renderType != RenderType.None)
throw new InvalidOperationException($"BeginWorld called with renderType = {renderType}, expected RenderType.None.");
BeginFrame();
if (worldSheet == null)
throw new InvalidOperationException($"BeginWorld called before SetMaximumViewportSize has been set.");
if (worldSprite == null || worldViewport.Size != worldSprite.Bounds.Size)
worldSprite = new Sprite(worldSheet, new Rectangle(int2.Zero, worldViewport.Size), TextureChannel.RGBA);
}
worldBuffer.Bind();
if (worldBufferSize != lastWorldBufferSize || lastWorldViewport != worldViewport)
if (lastWorldViewport != worldViewport)
{
var depthScale = worldBufferSize.Height / (worldBufferSize.Height + depthMargin);
WorldSpriteRenderer.SetViewportParams(worldBufferSize, depthScale, depthScale / 2, worldViewport.Location);
WorldModelRenderer.SetViewportParams(worldBufferSize, worldViewport.Location);
var depthScale = worldSheet.Size.Height / (worldSheet.Size.Height + depthMargin);
WorldSpriteRenderer.SetViewportParams(worldSheet.Size, depthScale, depthScale / 2, worldViewport.Location);
WorldModelRenderer.SetViewportParams(worldSheet.Size, worldViewport.Location);
lastWorldViewport = worldViewport;
lastWorldBufferSize = worldBufferSize;
}
renderType = RenderType.World;

View File

@@ -10,6 +10,7 @@
#endregion
using System.Diagnostics;
using OpenRA.Graphics;
using OpenRA.Support;
using OpenRA.Widgets;
@@ -18,7 +19,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public class PerfDebugLogic : ChromeLogic
{
[ObjectCreator.UseCtor]
public PerfDebugLogic(Widget widget)
public PerfDebugLogic(Widget widget, WorldRenderer worldRenderer)
{
var perfGraph = widget.Get("GRAPH_BG");
perfGraph.IsVisible = () => Game.Settings.Debug.PerfGraph;
@@ -40,7 +41,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
fpsReferenceFrame = Game.RenderFrame;
}
return $"FPS: {fps}\nTick {Game.LocalTick} @ {PerfHistory.Items["tick_time"].Average(Game.Settings.Debug.Samples):F1} ms\nRender {Game.RenderFrame} @ {PerfHistory.Items["render"].Average(Game.Settings.Debug.Samples):F1} ms\nBatches: {PerfHistory.Items["batches"].LastValue}";
var wfbSize = Game.Renderer.WorldFrameBufferSize;
var viewportSize = worldRenderer.Viewport.Rectangle.Size;
return $"FPS: {fps}\nTick {Game.LocalTick} @ {PerfHistory.Items["tick_time"].Average(Game.Settings.Debug.Samples):F1} ms\n" +
$"Render {Game.RenderFrame} @ {PerfHistory.Items["render"].Average(Game.Settings.Debug.Samples):F1} ms\n" +
$"Batches: {PerfHistory.Items["batches"].LastValue}\n" +
$"Viewport Size: {viewportSize.Width} x {viewportSize.Height}\n" +
$"WFB Size: {wfbSize.Width} x {wfbSize.Height}";
};
}
}

View File

@@ -53,7 +53,7 @@ Container@PERF_WIDGETS:
Children:
Label@PERF_TEXT:
X: WINDOW_RIGHT - 200
Y: WINDOW_BOTTOM - 70
Y: WINDOW_BOTTOM - 90
Width: 170
Height: 40
Contrast: true