Introduce Renderer.WorldBufferSnapshot().

This commit is contained in:
Paul Chote
2023-12-04 17:11:02 +00:00
committed by Gustas
parent 6a86a99fce
commit 6c56ea4c55
5 changed files with 18 additions and 14 deletions

View File

@@ -46,7 +46,6 @@ namespace OpenRA.Graphics
readonly List<IRenderable> renderablesBuffer = new(); readonly List<IRenderable> renderablesBuffer = new();
readonly IRenderer[] renderers; readonly IRenderer[] renderers;
readonly IRenderPostProcessPass[] postProcessPasses; readonly IRenderPostProcessPass[] postProcessPasses;
readonly ITexture postProcessTexture;
internal WorldRenderer(ModData modData, World world) internal WorldRenderer(ModData modData, World world)
{ {
@@ -75,8 +74,6 @@ namespace OpenRA.Graphics
debugVis = Exts.Lazy(() => world.WorldActor.TraitOrDefault<DebugVisualizations>()); debugVis = Exts.Lazy(() => world.WorldActor.TraitOrDefault<DebugVisualizations>());
postProcessPasses = world.WorldActor.TraitsImplementing<IRenderPostProcessPass>().ToArray(); postProcessPasses = world.WorldActor.TraitsImplementing<IRenderPostProcessPass>().ToArray();
if (postProcessPasses.Length > 0)
postProcessTexture = Game.Renderer.Context.CreateTexture();
} }
public void BeginFrame() public void BeginFrame()
@@ -323,18 +320,13 @@ namespace OpenRA.Graphics
void ApplyPostProcessing(PostProcessPassType type) void ApplyPostProcessing(PostProcessPassType type)
{ {
var size = Game.Renderer.WorldFrameBufferSize;
var rect = new Rectangle(0, 0, size.Width, size.Height);
foreach (var pass in postProcessPasses) foreach (var pass in postProcessPasses)
{ {
if (pass.Type != type || !pass.Enabled) if (pass.Type != type || !pass.Enabled)
continue; continue;
// Make a copy of the world texture to avoid reading and writing on the same buffer
Game.Renderer.Flush(); Game.Renderer.Flush();
postProcessTexture.SetDataFromReadBuffer(rect); pass.Draw(this);
Game.Renderer.Flush();
pass.Draw(this, postProcessTexture);
} }
} }

View File

@@ -47,6 +47,7 @@ namespace OpenRA
readonly IVertexBuffer<Vertex> tempVertexBuffer; readonly IVertexBuffer<Vertex> tempVertexBuffer;
readonly IIndexBuffer quadIndexBuffer; readonly IIndexBuffer quadIndexBuffer;
readonly Stack<Rectangle> scissorState = new(); readonly Stack<Rectangle> scissorState = new();
readonly ITexture worldBufferSnapshot;
IFrameBuffer screenBuffer; IFrameBuffer screenBuffer;
Sprite screenSprite; Sprite screenSprite;
@@ -60,6 +61,15 @@ namespace OpenRA
public Size WorldFrameBufferSize => worldSheet.Size; public Size WorldFrameBufferSize => worldSheet.Size;
public int WorldDownscaleFactor { get; private set; } = 1; public int WorldDownscaleFactor { get; private set; } = 1;
/// <summary>
/// Copies and returns the currently rendered world state as a temporary texture.
/// </summary>
public ITexture WorldBufferSnapshot()
{
worldBufferSnapshot.SetDataFromReadBuffer(new Rectangle(int2.Zero, worldSheet.Size));
return worldBufferSnapshot;
}
SheetBuilder fontSheetBuilder; SheetBuilder fontSheetBuilder;
readonly IPlatform platform; readonly IPlatform platform;
@@ -98,6 +108,7 @@ namespace OpenRA
tempVertexBuffer = Context.CreateVertexBuffer<Vertex>(TempVertexBufferSize); tempVertexBuffer = Context.CreateVertexBuffer<Vertex>(TempVertexBufferSize);
quadIndexBuffer = Context.CreateIndexBuffer(Util.CreateQuadIndices(TempIndexBufferSize / 6)); quadIndexBuffer = Context.CreateIndexBuffer(Util.CreateQuadIndices(TempIndexBufferSize / 6));
worldBufferSnapshot = Context.CreateTexture();
} }
static Size GetResolution(GraphicSettings graphicsSettings) static Size GetResolution(GraphicSettings graphicsSettings)
@@ -525,6 +536,7 @@ namespace OpenRA
{ {
worldBuffer.Dispose(); worldBuffer.Dispose();
screenBuffer.Dispose(); screenBuffer.Dispose();
worldBufferSnapshot.Dispose();
tempVertexBuffer.Dispose(); tempVertexBuffer.Dispose();
quadIndexBuffer.Dispose(); quadIndexBuffer.Dispose();
fontSheetBuilder?.Dispose(); fontSheetBuilder?.Dispose();

View File

@@ -467,7 +467,7 @@ namespace OpenRA.Traits
{ {
PostProcessPassType Type { get; } PostProcessPassType Type { get; }
bool Enabled { get; } bool Enabled { get; }
void Draw(WorldRenderer wr, ITexture worldTexture); void Draw(WorldRenderer wr);
} }
[Flags] [Flags]

View File

@@ -84,7 +84,7 @@ namespace OpenRA.Mods.Cnc.Traits
PostProcessPassType IRenderPostProcessPass.Type => PostProcessPassType.AfterWorld; PostProcessPassType IRenderPostProcessPass.Type => PostProcessPassType.AfterWorld;
bool IRenderPostProcessPass.Enabled => vortices.Count > 0; bool IRenderPostProcessPass.Enabled => vortices.Count > 0;
void IRenderPostProcessPass.Draw(WorldRenderer wr, ITexture worldTexture) void IRenderPostProcessPass.Draw(WorldRenderer wr)
{ {
var scroll = wr.Viewport.TopLeft; var scroll = wr.Viewport.TopLeft;
var size = renderer.WorldFrameBufferSize; var size = renderer.WorldFrameBufferSize;
@@ -94,7 +94,7 @@ namespace OpenRA.Mods.Cnc.Traits
shader.SetVec("Scroll", scroll.X, scroll.Y); shader.SetVec("Scroll", scroll.X, scroll.Y);
shader.SetVec("p1", width, height); shader.SetVec("p1", width, height);
shader.SetVec("p2", -1, -1); shader.SetVec("p2", -1, -1);
shader.SetTexture("WorldTexture", worldTexture); shader.SetTexture("WorldTexture", Game.Renderer.WorldBufferSnapshot());
shader.SetTexture("VortexTexture", vortexSheet.GetTexture()); shader.SetTexture("VortexTexture", vortexSheet.GetTexture());
shader.PrepareRender(); shader.PrepareRender();
foreach (var (pos, frame) in vortices) foreach (var (pos, frame) in vortices)

View File

@@ -42,9 +42,9 @@ namespace OpenRA.Mods.Common.Traits
PostProcessPassType IRenderPostProcessPass.Type => type; PostProcessPassType IRenderPostProcessPass.Type => type;
bool IRenderPostProcessPass.Enabled => Enabled; bool IRenderPostProcessPass.Enabled => Enabled;
void IRenderPostProcessPass.Draw(WorldRenderer wr, ITexture worldTexture) void IRenderPostProcessPass.Draw(WorldRenderer wr)
{ {
shader.SetTexture("WorldTexture", worldTexture); shader.SetTexture("WorldTexture", Game.Renderer.WorldBufferSnapshot());
PrepareRender(wr, shader); PrepareRender(wr, shader);
shader.PrepareRender(); shader.PrepareRender();
renderer.DrawBatch(buffer, shader, 0, 6, PrimitiveType.TriangleList); renderer.DrawBatch(buffer, shader, 0, 6, PrimitiveType.TriangleList);