Skip to content

Commit

Permalink
Merge pull request #1672 from vchelaru/1664-discussion-talk-about-how…
Browse files Browse the repository at this point in the history
…-to-exclude-layers-from-post-processing

Added support for camera-specific post processing effects
  • Loading branch information
vchelaru authored Jan 11, 2025
2 parents 1e4150b + c921055 commit 1d51944
Show file tree
Hide file tree
Showing 9 changed files with 4,691 additions and 4,702 deletions.
4,081 changes: 2,023 additions & 2,058 deletions Engines/FlatRedBallXNA/FlatRedBall/Camera.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Graphics\Particle\EmitterList.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Graphics\Particle\TimedRemovalRecord.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Graphics\PostProcessing\IPostProcess.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Graphics\PostProcessing\PostProcessLogic.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Graphics\PostProcessing\SwapChain.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Graphics\RenderBreak.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Graphics\Renderer.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ public enum TextureCoordinateType
}


public enum CameraModelCullMode
{
Frustum,
None
}

public enum CameraCullMode
{
UnrotatedDownZ,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ public void Emit(SpriteList spriteList)

if (EmissionSettings.Billboarded)
{
SpriteManager.Camera.AddSpriteToBillboard(tempParticle);
tempParticle.IsBillboarded = true;
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace FlatRedBall.Graphics.PostProcessing;

internal static class PostProcessLogic
{
public static void DrawWithPostProcessing(List<IPostProcess> postProcesses,
SwapChain swapChain, Action drawCall)
{
bool hasGlobalPostProcessing = false;

foreach (var item in postProcesses)
{
if (item.IsEnabled)
{
hasGlobalPostProcessing = true;
break;
}
}
#if DEBUG
if (hasGlobalPostProcessing && swapChain == null)
{
throw new InvalidOperationException("SwapChain must be set prior to rendering the first frame if using any post processing");
}
#endif
if (hasGlobalPostProcessing)
{
SetStatesAndRenderTargetForPostProcessing(swapChain);
}
else
{
// Just in case we removed all post processing, but are on "B"
swapChain?.ResetForFrame();
}

drawCall();

if (hasGlobalPostProcessing)
{
ApplyPostProcessing(postProcesses, swapChain);
}
}

static void ApplyPostProcessing(List<IPostProcess> postProcesses, SwapChain swapChain)
{
foreach (var postProcess in postProcesses)
{
if (postProcess.IsEnabled)
{
#if DEBUG
Renderer.RenderBreaks.Add(new RenderBreak() { ObjectCausingBreak = postProcess });
#endif
swapChain.Swap();
postProcess.Apply(swapChain.CurrentTexture);
}
}

#if DEBUG
Renderer.RenderBreaks.Add(new RenderBreak() { ObjectCausingBreak = swapChain });
#endif
swapChain.RenderToScreen();
}

static void SetStatesAndRenderTargetForPostProcessing(SwapChain swapChain)
{
Renderer.ForceSetBlendOperation();
Renderer.ForceSetColorOperation(Renderer.ColorOperation);

swapChain.ResetForFrame();

// Set the render target before drawing anything
Renderer.GraphicsDevice.SetRenderTarget(swapChain.CurrentRenderTarget);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public class SwapChain
public RenderTarget2D CurrentRenderTarget => isSwapped ? RenderTargetB : RenderTargetA;
public RenderTarget2D CurrentTexture => isSwapped ? RenderTargetA : RenderTargetB;

public int Width => RenderTargetA?.Width ?? 0;
public int Height => RenderTargetA?.Height ?? 0;

#region Construction / initialization

public SwapChain(int width, int height, bool shouldSwapClearRenderTarget = true,
SurfaceFormat? surfaceFormat = null)
Expand All @@ -32,6 +36,45 @@ public SwapChain(int width, int height, bool shouldSwapClearRenderTarget = true,
spriteBatch = new SpriteBatch(FlatRedBallServices.GraphicsDevice);
}


internal static void CreateRenderTarget(ref RenderTarget2D renderTarget, int width, int height)
{
CreateOrUpdateRenderTarget(ref renderTarget, width, height, FlatRedBallServices.GraphicsDevice.DisplayMode.Format, RenderTargetUsage.DiscardContents);
}

internal static void CreateRenderTarget(ref RenderTarget2D renderTarget, int width, int height, SurfaceFormat surfaceFormat)
{
CreateOrUpdateRenderTarget(ref renderTarget, width, height, surfaceFormat, RenderTargetUsage.DiscardContents);
}

/// <summary>
/// Assigns a new render target to the argument renderTarget if the argument render target size, format, or usage
/// does not match the parameters. If the argument renderTarget is not null then it is disposed.
/// </summary>
/// <param name="renderTarget"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="surfaceFormat"></param>
/// <param name="renderTargetUsage"></param>
internal static void CreateOrUpdateRenderTarget(ref RenderTarget2D renderTarget, int width, int height, SurfaceFormat surfaceFormat, RenderTargetUsage renderTargetUsage)
{
if (renderTarget == null
|| renderTarget.Width != width
|| renderTarget.Height != height
|| renderTarget.Format != surfaceFormat
|| renderTarget.RenderTargetUsage != renderTargetUsage)
{
renderTarget?.Dispose();

lock (FlatRedBallServices.GraphicsDevice)
{
renderTarget = new RenderTarget2D(FlatRedBallServices.GraphicsDevice, width, height, false, surfaceFormat, (DepthFormat)0, 0, renderTargetUsage);
}
}
}

#endregion

public void UpdateRenderTargetSize(int newWidth, int newHeight)
{
var shouldRecreate = RenderTargetA.Width != newWidth || RenderTargetA.Height != newHeight;
Expand All @@ -45,15 +88,17 @@ public void UpdateRenderTargetSize(int newWidth, int newHeight)
}
}

#region Rendering

public void RenderToScreen()
{
FlatRedBallServices.GraphicsDevice.SetRenderTarget(null);

// ...and draw the RenderTarget to the screen
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
var destinationRectangle = new Microsoft.Xna.Framework.Rectangle(0, 0, Renderer.SwapChain.CurrentRenderTarget.Width, Renderer.SwapChain.CurrentRenderTarget.Height);
var destinationRectangle = new Microsoft.Xna.Framework.Rectangle(0, 0, CurrentRenderTarget.Width, CurrentRenderTarget.Height);

spriteBatch.Draw(Renderer.SwapChain.CurrentRenderTarget, destinationRectangle,
spriteBatch.Draw(CurrentRenderTarget, destinationRectangle,
Microsoft.Xna.Framework.Color.White);
spriteBatch.End();
}
Expand All @@ -66,40 +111,14 @@ public void ResetForFrame()
public void Swap()
{
isSwapped = !isSwapped;
FlatRedBallServices.GraphicsDevice.SetRenderTarget(Renderer.SwapChain.CurrentRenderTarget);
FlatRedBallServices.GraphicsDevice.SetRenderTarget(CurrentRenderTarget);
if(ShouldSwapClearRenderTarget)
{
FlatRedBallServices.GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.Transparent);
}
}

#endregion

internal static void CreateRenderTarget(ref RenderTarget2D renderTarget, int width, int height)
{
CreateRenderTarget(ref renderTarget, width, height, FlatRedBallServices.GraphicsDevice.DisplayMode.Format, RenderTargetUsage.DiscardContents);
}

internal static void CreateRenderTarget(ref RenderTarget2D renderTarget, int width, int height, SurfaceFormat surfaceFormat)
{
CreateRenderTarget(ref renderTarget, width, height, surfaceFormat, RenderTargetUsage.DiscardContents);
}

internal static void CreateRenderTarget(ref RenderTarget2D renderTarget, int width, int height, SurfaceFormat surfaceFormat, RenderTargetUsage renderTargetUsage)
{
if (renderTarget == null
|| renderTarget.Width != width
|| renderTarget.Height != height
|| renderTarget.Format != surfaceFormat
|| renderTarget.RenderTargetUsage != renderTargetUsage)
{
if (renderTarget != null)
renderTarget.Dispose();

lock (FlatRedBallServices.GraphicsDevice)
{
renderTarget = new RenderTarget2D(FlatRedBallServices.GraphicsDevice, width, height, false, surfaceFormat, (DepthFormat)0, 0, renderTargetUsage);
}
}
}
}
}
Loading

0 comments on commit 1d51944

Please sign in to comment.