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
|
else
|
||||||
Zoom = Zoom.Clamp(minZoom, maxZoom);
|
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>())
|
foreach (var t in worldRenderer.World.WorldActor.TraitsImplementing<INotifyViewportZoomExtentsChanged>())
|
||||||
t.ViewportZoomExtentsChanged(minZoom, maxZoom);
|
t.ViewportZoomExtentsChanged(minZoom, maxZoom);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,11 @@ namespace OpenRA
|
|||||||
Sprite screenSprite;
|
Sprite screenSprite;
|
||||||
|
|
||||||
IFrameBuffer worldBuffer;
|
IFrameBuffer worldBuffer;
|
||||||
|
Sheet worldSheet;
|
||||||
Sprite worldSprite;
|
Sprite worldSprite;
|
||||||
|
|
||||||
|
public Size WorldFrameBufferSize => worldSheet.Size;
|
||||||
|
|
||||||
SheetBuilder fontSheetBuilder;
|
SheetBuilder fontSheetBuilder;
|
||||||
readonly IPlatform platform;
|
readonly IPlatform platform;
|
||||||
|
|
||||||
@@ -59,7 +62,6 @@ namespace OpenRA
|
|||||||
|
|
||||||
Size lastBufferSize = new Size(-1, -1);
|
Size lastBufferSize = new Size(-1, -1);
|
||||||
|
|
||||||
Size lastWorldBufferSize = new Size(-1, -1);
|
|
||||||
Rectangle lastWorldViewport = Rectangle.Empty;
|
Rectangle lastWorldViewport = Rectangle.Empty;
|
||||||
ITexture currentPaletteTexture;
|
ITexture currentPaletteTexture;
|
||||||
IBatchRenderer currentBatchRenderer;
|
IBatchRenderer currentBatchRenderer;
|
||||||
@@ -178,14 +180,9 @@ namespace OpenRA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginWorld(Rectangle worldViewport)
|
public void SetMaximumViewportSize(Size size)
|
||||||
{
|
{
|
||||||
if (renderType != RenderType.None)
|
var worldBufferSize = size.NextPowerOf2();
|
||||||
throw new InvalidOperationException($"BeginWorld called with renderType = {renderType}, expected RenderType.None.");
|
|
||||||
|
|
||||||
BeginFrame();
|
|
||||||
|
|
||||||
var worldBufferSize = worldViewport.Size.NextPowerOf2();
|
|
||||||
if (worldSprite == null || worldSprite.Sheet.Size != worldBufferSize)
|
if (worldSprite == null || worldSprite.Sheet.Size != worldBufferSize)
|
||||||
{
|
{
|
||||||
worldBuffer?.Dispose();
|
worldBuffer?.Dispose();
|
||||||
@@ -195,24 +192,36 @@ namespace OpenRA
|
|||||||
|
|
||||||
// Pixel art scaling mode is a customized bilinear sampling
|
// Pixel art scaling mode is a customized bilinear sampling
|
||||||
worldBuffer.Texture.ScaleFilter = TextureScaleFilter.Linear;
|
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)
|
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);
|
worldSprite = new Sprite(worldSheet, new Rectangle(int2.Zero, worldViewport.Size), TextureChannel.RGBA);
|
||||||
}
|
|
||||||
|
|
||||||
worldBuffer.Bind();
|
worldBuffer.Bind();
|
||||||
|
|
||||||
if (worldBufferSize != lastWorldBufferSize || lastWorldViewport != worldViewport)
|
if (lastWorldViewport != worldViewport)
|
||||||
{
|
{
|
||||||
var depthScale = worldBufferSize.Height / (worldBufferSize.Height + depthMargin);
|
var depthScale = worldSheet.Size.Height / (worldSheet.Size.Height + depthMargin);
|
||||||
WorldSpriteRenderer.SetViewportParams(worldBufferSize, depthScale, depthScale / 2, worldViewport.Location);
|
WorldSpriteRenderer.SetViewportParams(worldSheet.Size, depthScale, depthScale / 2, worldViewport.Location);
|
||||||
WorldModelRenderer.SetViewportParams(worldBufferSize, worldViewport.Location);
|
WorldModelRenderer.SetViewportParams(worldSheet.Size, worldViewport.Location);
|
||||||
|
|
||||||
lastWorldViewport = worldViewport;
|
lastWorldViewport = worldViewport;
|
||||||
lastWorldBufferSize = worldBufferSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderType = RenderType.World;
|
renderType = RenderType.World;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using OpenRA.Graphics;
|
||||||
using OpenRA.Support;
|
using OpenRA.Support;
|
||||||
using OpenRA.Widgets;
|
using OpenRA.Widgets;
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
public class PerfDebugLogic : ChromeLogic
|
public class PerfDebugLogic : ChromeLogic
|
||||||
{
|
{
|
||||||
[ObjectCreator.UseCtor]
|
[ObjectCreator.UseCtor]
|
||||||
public PerfDebugLogic(Widget widget)
|
public PerfDebugLogic(Widget widget, WorldRenderer worldRenderer)
|
||||||
{
|
{
|
||||||
var perfGraph = widget.Get("GRAPH_BG");
|
var perfGraph = widget.Get("GRAPH_BG");
|
||||||
perfGraph.IsVisible = () => Game.Settings.Debug.PerfGraph;
|
perfGraph.IsVisible = () => Game.Settings.Debug.PerfGraph;
|
||||||
@@ -40,7 +41,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
fpsReferenceFrame = Game.RenderFrame;
|
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:
|
Children:
|
||||||
Label@PERF_TEXT:
|
Label@PERF_TEXT:
|
||||||
X: WINDOW_RIGHT - 200
|
X: WINDOW_RIGHT - 200
|
||||||
Y: WINDOW_BOTTOM - 70
|
Y: WINDOW_BOTTOM - 90
|
||||||
Width: 170
|
Width: 170
|
||||||
Height: 40
|
Height: 40
|
||||||
Contrast: true
|
Contrast: true
|
||||||
|
|||||||
Reference in New Issue
Block a user