Set world framebuffer size based on minimum zoom.
This avoids reallocating buffers each time the player changes zoom level.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
public void BeginWorld(Rectangle worldViewport)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var worldSheet = new Sheet(SheetType.BGRA, worldBuffer.Texture);
|
||||
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;
|
||||
|
||||
@@ -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}";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user