Introduce World and UI rendering phases.
This commit is contained in:
@@ -679,21 +679,18 @@ namespace OpenRA
|
|||||||
}
|
}
|
||||||
|
|
||||||
// worldRenderer is null during the initial install/download screen
|
// worldRenderer is null during the initial install/download screen
|
||||||
if (worldRenderer != null)
|
// World rendering is disabled while the loading screen is displayed
|
||||||
|
// Use worldRenderer.World instead of OrderManager.World to avoid a rendering mismatch while processing orders
|
||||||
|
if (worldRenderer != null && !worldRenderer.World.IsLoadingGameSave)
|
||||||
{
|
{
|
||||||
Renderer.BeginFrame(worldRenderer.Viewport.TopLeft, worldRenderer.Viewport.Zoom);
|
Renderer.BeginWorld(worldRenderer.Viewport.TopLeft, worldRenderer.Viewport.Zoom);
|
||||||
Sound.SetListenerPosition(worldRenderer.Viewport.CenterPosition);
|
Sound.SetListenerPosition(worldRenderer.Viewport.CenterPosition);
|
||||||
|
worldRenderer.Draw();
|
||||||
// World rendering is disabled while the loading screen is displayed
|
|
||||||
// Use worldRenderer.World instead of OrderManager.World to avoid a rendering mismatch while processing orders
|
|
||||||
if (!worldRenderer.World.IsLoadingGameSave)
|
|
||||||
worldRenderer.Draw();
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
Renderer.BeginFrame(int2.Zero, 1f);
|
|
||||||
|
|
||||||
using (new PerfSample("render_widgets"))
|
using (new PerfSample("render_widgets"))
|
||||||
{
|
{
|
||||||
|
Renderer.BeginUI();
|
||||||
Ui.Draw();
|
Ui.Draw();
|
||||||
|
|
||||||
if (ModData != null && ModData.CursorProvider != null)
|
if (ModData != null && ModData.CursorProvider != null)
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public sealed class Renderer : IDisposable
|
public sealed class Renderer : IDisposable
|
||||||
{
|
{
|
||||||
|
enum RenderType { None, World, UI }
|
||||||
|
|
||||||
public SpriteRenderer WorldSpriteRenderer { get; private set; }
|
public SpriteRenderer WorldSpriteRenderer { get; private set; }
|
||||||
public RgbaSpriteRenderer WorldRgbaSpriteRenderer { get; private set; }
|
public RgbaSpriteRenderer WorldRgbaSpriteRenderer { get; private set; }
|
||||||
public RgbaColorRenderer WorldRgbaColorRenderer { get; private set; }
|
public RgbaColorRenderer WorldRgbaColorRenderer { get; private set; }
|
||||||
@@ -54,6 +56,7 @@ namespace OpenRA
|
|||||||
float lastZoom = -1f;
|
float lastZoom = -1f;
|
||||||
ITexture currentPaletteTexture;
|
ITexture currentPaletteTexture;
|
||||||
IBatchRenderer currentBatchRenderer;
|
IBatchRenderer currentBatchRenderer;
|
||||||
|
RenderType renderType = RenderType.None;
|
||||||
|
|
||||||
public Renderer(IPlatform platform, GraphicSettings graphicSettings)
|
public Renderer(IPlatform platform, GraphicSettings graphicSettings)
|
||||||
{
|
{
|
||||||
@@ -125,7 +128,7 @@ namespace OpenRA
|
|||||||
depthOffset = depthScale / 2;
|
depthOffset = depthScale / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginFrame(int2 scroll, float zoom)
|
void BeginFrame()
|
||||||
{
|
{
|
||||||
Context.Clear();
|
Context.Clear();
|
||||||
|
|
||||||
@@ -151,33 +154,50 @@ namespace OpenRA
|
|||||||
}
|
}
|
||||||
|
|
||||||
screenBuffer.Bind();
|
screenBuffer.Bind();
|
||||||
SetViewportParams(scroll, zoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetViewportParams(int2 scroll, float zoom)
|
|
||||||
{
|
|
||||||
// In HiDPI windows we follow Apple's convention of defining window coordinates as for standard resolution windows
|
// In HiDPI windows we follow Apple's convention of defining window coordinates as for standard resolution windows
|
||||||
// but to have a higher resolution backing surface with more than 1 texture pixel per viewport pixel.
|
// but to have a higher resolution backing surface with more than 1 texture pixel per viewport pixel.
|
||||||
// We must convert the surface buffer size to a viewport size - in general this is NOT just the window size
|
// We must convert the surface buffer size to a viewport size - in general this is NOT just the window size
|
||||||
// rounded to the next power of two, as the NextPowerOf2 calculation is done in the surface pixel coordinates
|
// rounded to the next power of two, as the NextPowerOf2 calculation is done in the surface pixel coordinates
|
||||||
var scale = Window.WindowScale;
|
var scale = Window.WindowScale;
|
||||||
var surfaceBufferSize = Window.SurfaceSize.NextPowerOf2();
|
|
||||||
var bufferSize = new Size((int)(surfaceBufferSize.Width / scale), (int)(surfaceBufferSize.Height / scale));
|
var bufferSize = new Size((int)(surfaceBufferSize.Width / scale), (int)(surfaceBufferSize.Height / scale));
|
||||||
|
if (lastBufferSize != bufferSize)
|
||||||
// PERF: Calling SetViewportParams on each renderer is slow. Only call it when things change.
|
|
||||||
// If zoom evaluates as different due to floating point weirdness that's OK, it will be going away soon
|
|
||||||
if (lastBufferSize != bufferSize || lastScroll != scroll || lastZoom != zoom)
|
|
||||||
{
|
{
|
||||||
if (lastBufferSize != bufferSize)
|
SpriteRenderer.SetViewportParams(bufferSize, 0f, 0f, 1f, int2.Zero);
|
||||||
SpriteRenderer.SetViewportParams(bufferSize, 0f, 0f, 1f, int2.Zero);
|
lastBufferSize = bufferSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BeginWorld(int2 scroll, float zoom)
|
||||||
|
{
|
||||||
|
if (renderType != RenderType.None)
|
||||||
|
throw new InvalidOperationException("BeginWorld called with renderType = {0}, expected RenderType.None.".F(renderType));
|
||||||
|
|
||||||
|
var oldLastBufferSize = lastBufferSize;
|
||||||
|
BeginFrame();
|
||||||
|
|
||||||
|
var scale = Window.WindowScale;
|
||||||
|
var surfaceSize = Window.SurfaceSize;
|
||||||
|
var surfaceBufferSize = surfaceSize.NextPowerOf2();
|
||||||
|
var bufferSize = new Size((int)(surfaceBufferSize.Width / scale), (int)(surfaceBufferSize.Height / scale));
|
||||||
|
if (oldLastBufferSize != bufferSize || lastScroll != scroll || lastZoom != zoom)
|
||||||
|
{
|
||||||
WorldSpriteRenderer.SetViewportParams(bufferSize, depthScale, depthOffset, zoom, scroll);
|
WorldSpriteRenderer.SetViewportParams(bufferSize, depthScale, depthOffset, zoom, scroll);
|
||||||
WorldModelRenderer.SetViewportParams(bufferSize, zoom, scroll);
|
WorldModelRenderer.SetViewportParams(bufferSize, zoom, scroll);
|
||||||
|
|
||||||
lastBufferSize = bufferSize;
|
|
||||||
lastScroll = scroll;
|
lastScroll = scroll;
|
||||||
lastZoom = zoom;
|
lastZoom = zoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderType = RenderType.World;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BeginUI()
|
||||||
|
{
|
||||||
|
if (renderType == RenderType.None)
|
||||||
|
BeginFrame();
|
||||||
|
|
||||||
|
renderType = RenderType.UI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPalette(HardwarePalette palette)
|
public void SetPalette(HardwarePalette palette)
|
||||||
@@ -195,6 +215,9 @@ namespace OpenRA
|
|||||||
|
|
||||||
public void EndFrame(IInputHandler inputHandler)
|
public void EndFrame(IInputHandler inputHandler)
|
||||||
{
|
{
|
||||||
|
if (renderType != RenderType.UI)
|
||||||
|
throw new InvalidOperationException("EndFrame called with renderType = {0}, expected RenderType.UI.".F(renderType));
|
||||||
|
|
||||||
Flush();
|
Flush();
|
||||||
|
|
||||||
screenBuffer.Unbind();
|
screenBuffer.Unbind();
|
||||||
@@ -207,6 +230,8 @@ namespace OpenRA
|
|||||||
|
|
||||||
Window.PumpInput(inputHandler);
|
Window.PumpInput(inputHandler);
|
||||||
Context.Present();
|
Context.Present();
|
||||||
|
|
||||||
|
renderType = RenderType.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawBatch(Vertex[] vertices, int numVertices, PrimitiveType type)
|
public void DrawBatch(Vertex[] vertices, int numVertices, PrimitiveType type)
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ namespace OpenRA.Mods.Cnc
|
|||||||
loadTimer.Restart();
|
loadTimer.Restart();
|
||||||
|
|
||||||
loadTick = ++loadTick % 8;
|
loadTick = ++loadTick % 8;
|
||||||
r.BeginFrame(int2.Zero, 1f);
|
r.BeginUI();
|
||||||
r.RgbaSpriteRenderer.DrawSprite(gdiLogo, gdiPos);
|
r.RgbaSpriteRenderer.DrawSprite(gdiLogo, gdiPos);
|
||||||
r.RgbaSpriteRenderer.DrawSprite(nodLogo, nodPos);
|
r.RgbaSpriteRenderer.DrawSprite(nodLogo, nodPos);
|
||||||
r.RgbaSpriteRenderer.DrawSprite(evaLogo, evaPos);
|
r.RgbaSpriteRenderer.DrawSprite(evaLogo, evaPos);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.LoadScreens
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Draw a black screen
|
// Draw a black screen
|
||||||
Game.Renderer.BeginFrame(int2.Zero, 1f);
|
Game.Renderer.BeginUI();
|
||||||
Game.Renderer.EndFrame(new NullInputHandler());
|
Game.Renderer.EndFrame(new NullInputHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.LoadScreens
|
|||||||
var text = messages.Random(Game.CosmeticRandom);
|
var text = messages.Random(Game.CosmeticRandom);
|
||||||
var textSize = r.Fonts["Bold"].Measure(text);
|
var textSize = r.Fonts["Bold"].Measure(text);
|
||||||
|
|
||||||
r.BeginFrame(int2.Zero, 1f);
|
r.BeginUI();
|
||||||
|
|
||||||
if (stripe != null)
|
if (stripe != null)
|
||||||
WidgetUtils.FillRectWithSprite(stripeRect, stripe);
|
WidgetUtils.FillRectWithSprite(stripeRect, stripe);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.LoadScreens
|
|||||||
if (r == null)
|
if (r == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
r.BeginFrame(int2.Zero, 1f);
|
r.BeginUI();
|
||||||
WidgetUtils.FillRectWithSprite(bounds, sprite);
|
WidgetUtils.FillRectWithSprite(bounds, sprite);
|
||||||
r.EndFrame(new NullInputHandler());
|
r.EndFrame(new NullInputHandler());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user