Refactor PostProcessEffect to support C++ scripting
This commit is contained in:
@@ -33,7 +33,10 @@ namespace FlaxEditor.Gizmo
|
||||
public IEditorPrimitivesOwner Viewport;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Order => -100;
|
||||
public EditorPrimitives()
|
||||
{
|
||||
Order = -100;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
|
||||
|
||||
@@ -114,7 +114,10 @@ namespace FlaxEditor.Gizmo
|
||||
protected bool HasDataReady => _enabled && _material && _outlineMaterial.IsLoaded;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanRender => _enabled && _material && _outlineMaterial.IsLoaded && SelectionGetter().Count > 0;
|
||||
public override bool CanRender()
|
||||
{
|
||||
return _enabled && _material && _outlineMaterial.IsLoaded && SelectionGetter().Count > 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
|
||||
|
||||
@@ -20,21 +20,18 @@ namespace FlaxEditor.Tools.Foliage
|
||||
public EditFoliageGizmoMode GizmoMode;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanRender
|
||||
public override bool CanRender()
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!HasDataReady)
|
||||
return false;
|
||||
if (!HasDataReady)
|
||||
return false;
|
||||
|
||||
var foliage = GizmoMode.SelectedFoliage;
|
||||
if (!foliage)
|
||||
return false;
|
||||
var instanceIndex = GizmoMode.SelectedInstanceIndex;
|
||||
if (instanceIndex < 0 || instanceIndex >= foliage.InstancesCount)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
var foliage = GizmoMode.SelectedFoliage;
|
||||
if (!foliage)
|
||||
return false;
|
||||
var instanceIndex = GizmoMode.SelectedInstanceIndex;
|
||||
if (instanceIndex < 0 || instanceIndex >= foliage.InstancesCount)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -71,13 +71,17 @@ namespace FlaxEditor.Viewport
|
||||
public SceneRenderTask Task;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Order => -10000000;
|
||||
public EditorSpritesRenderer()
|
||||
{
|
||||
Order = -10000000;
|
||||
UseSingleTarget = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool UseSingleTarget => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanRender => (Task.View.Flags & ViewFlags.EditorSprites) == ViewFlags.EditorSprites && Level.ScenesCount != 0 && base.CanRender;
|
||||
public override bool CanRender()
|
||||
{
|
||||
return (Task.View.Flags & ViewFlags.EditorSprites) == ViewFlags.EditorSprites && Level.ScenesCount != 0 && base.CanRender();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
|
||||
@@ -202,13 +206,13 @@ namespace FlaxEditor.Viewport
|
||||
// Create post effects
|
||||
SelectionOutline = Object.New<SelectionOutline>();
|
||||
SelectionOutline.SelectionGetter = () => TransformGizmo.SelectedParents;
|
||||
Task.CustomPostFx.Add(SelectionOutline);
|
||||
Task.AddCustomPostFx(SelectionOutline);
|
||||
EditorPrimitives = Object.New<EditorPrimitives>();
|
||||
EditorPrimitives.Viewport = this;
|
||||
Task.CustomPostFx.Add(EditorPrimitives);
|
||||
Task.AddCustomPostFx(EditorPrimitives);
|
||||
_editorSpritesRenderer = Object.New<EditorSpritesRenderer>();
|
||||
_editorSpritesRenderer.Task = Task;
|
||||
Task.CustomPostFx.Add(_editorSpritesRenderer);
|
||||
Task.AddCustomPostFx(_editorSpritesRenderer);
|
||||
|
||||
// Add transformation gizmo
|
||||
TransformGizmo = new TransformGizmo(this);
|
||||
@@ -396,16 +400,13 @@ namespace FlaxEditor.Viewport
|
||||
if (_customSelectionOutline != null)
|
||||
{
|
||||
Object.Destroy(ref _customSelectionOutline);
|
||||
|
||||
Task.CustomPostFx.Remove(_customSelectionOutline);
|
||||
|
||||
Task.CustomPostFx.Add(customSelectionOutline ? customSelectionOutline : SelectionOutline);
|
||||
Task.RemoveCustomPostFx(_customSelectionOutline);
|
||||
Task.AddCustomPostFx(customSelectionOutline ? customSelectionOutline : SelectionOutline);
|
||||
}
|
||||
else if (customSelectionOutline != null)
|
||||
{
|
||||
Task.CustomPostFx.Remove(SelectionOutline);
|
||||
|
||||
Task.CustomPostFx.Add(customSelectionOutline);
|
||||
Task.RemoveCustomPostFx(SelectionOutline);
|
||||
Task.AddCustomPostFx(customSelectionOutline);
|
||||
}
|
||||
|
||||
_customSelectionOutline = customSelectionOutline;
|
||||
@@ -509,20 +510,20 @@ namespace FlaxEditor.Viewport
|
||||
|
||||
// Render editor primitives, gizmo and debug shapes in debug view modes
|
||||
// Note: can use Output buffer as both input and output because EditorPrimitives is using a intermediate buffers
|
||||
if (EditorPrimitives && EditorPrimitives.CanRender)
|
||||
if (EditorPrimitives && EditorPrimitives.CanRender())
|
||||
{
|
||||
EditorPrimitives.Render(context, ref renderContext, task.Output, task.Output);
|
||||
}
|
||||
|
||||
// Render editor sprites
|
||||
if (_editorSpritesRenderer && _editorSpritesRenderer.CanRender)
|
||||
if (_editorSpritesRenderer && _editorSpritesRenderer.CanRender())
|
||||
{
|
||||
_editorSpritesRenderer.Render(context, ref renderContext, task.Output, task.Output);
|
||||
}
|
||||
|
||||
// Render selection outline
|
||||
var selectionOutline = _customSelectionOutline ?? SelectionOutline;
|
||||
if (selectionOutline && selectionOutline.CanRender)
|
||||
if (selectionOutline && selectionOutline.CanRender())
|
||||
{
|
||||
// Use temporary intermediate buffer
|
||||
var desc = task.Output.Description;
|
||||
|
||||
@@ -31,7 +31,11 @@ namespace FlaxEditor.Viewport
|
||||
{
|
||||
public PrefabWindowViewport Viewport;
|
||||
|
||||
public override bool CanRender => (Task.View.Flags & ViewFlags.EditorSprites) == ViewFlags.EditorSprites && Enabled;
|
||||
/// <inheritdoc />
|
||||
public override bool CanRender()
|
||||
{
|
||||
return (Task.View.Flags & ViewFlags.EditorSprites) == ViewFlags.EditorSprites && Enabled;
|
||||
}
|
||||
|
||||
protected override void Draw(ref RenderContext renderContext)
|
||||
{
|
||||
@@ -91,11 +95,11 @@ namespace FlaxEditor.Viewport
|
||||
// Create post effects
|
||||
SelectionOutline = FlaxEngine.Object.New<SelectionOutline>();
|
||||
SelectionOutline.SelectionGetter = () => TransformGizmo.SelectedParents;
|
||||
Task.CustomPostFx.Add(SelectionOutline);
|
||||
Task.AddCustomPostFx(SelectionOutline);
|
||||
_spritesRenderer = FlaxEngine.Object.New<PrefabSpritesRenderer>();
|
||||
_spritesRenderer.Task = Task;
|
||||
_spritesRenderer.Viewport = this;
|
||||
Task.CustomPostFx.Add(_spritesRenderer);
|
||||
Task.AddCustomPostFx(_spritesRenderer);
|
||||
|
||||
// Add transformation gizmo
|
||||
TransformGizmo = new TransformGizmo(this);
|
||||
@@ -270,13 +274,13 @@ namespace FlaxEditor.Viewport
|
||||
var task = renderContext.Task;
|
||||
|
||||
// Render editor sprites
|
||||
if (_spritesRenderer && _spritesRenderer.CanRender)
|
||||
if (_spritesRenderer && _spritesRenderer.CanRender())
|
||||
{
|
||||
_spritesRenderer.Render(context, ref renderContext, task.Output, task.Output);
|
||||
}
|
||||
|
||||
// Render selection outline
|
||||
if (SelectionOutline && SelectionOutline.CanRender)
|
||||
if (SelectionOutline && SelectionOutline.CanRender())
|
||||
{
|
||||
// Use temporary intermediate buffer
|
||||
var desc = task.Output.Description;
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
{
|
||||
_editorPrimitives = Object.New<EditorPrimitives>();
|
||||
_editorPrimitives.Viewport = this;
|
||||
Task.CustomPostFx.Add(_editorPrimitives);
|
||||
Task.AddCustomPostFx(_editorPrimitives);
|
||||
Task.PostRender += OnPostRender;
|
||||
var view = Task.View;
|
||||
view.Flags |= ViewFlags.CustomPostProcess;
|
||||
@@ -203,7 +203,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
|
||||
private void OnPostRender(GPUContext context, ref RenderContext renderContext)
|
||||
{
|
||||
if (renderContext.View.Mode != ViewMode.Default && _editorPrimitives && _editorPrimitives.CanRender)
|
||||
if (renderContext.View.Mode != ViewMode.Default && _editorPrimitives && _editorPrimitives.CanRender())
|
||||
{
|
||||
// Render editor primitives, gizmo and debug shapes in debug view modes
|
||||
// Note: can use Output buffer as both input and output because EditorPrimitives is using a intermediate buffers
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom postFx which can modify final image by processing it with material based filters.
|
||||
/// The base class for all post process effects used by the graphics pipeline.
|
||||
/// Allows to extend frame rendering logic and apply custom effects such as outline, night vision, contrast etc.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Override this class and implement custom post fx logic.
|
||||
/// Use <b>MainRenderTask.Instance.CustomPostFx.Add(myPostFx)</b> to attach your script to rendering.
|
||||
/// Or add script to camera.
|
||||
/// </remarks>
|
||||
public abstract class PostProcessEffect : Script
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this effect can be rendered.
|
||||
/// </summary>
|
||||
public virtual bool CanRender => Enabled;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether use a single render target as both input and output. Use this if your effect doesn't need to copy the input buffer to the output but can render directly to the single texture. Can be used to optimize game performance.
|
||||
/// </summary>
|
||||
public virtual bool UseSingleTarget => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the effect rendering location within rendering pipeline.
|
||||
/// </summary>
|
||||
public virtual PostProcessEffectLocation Location => PostProcessEffectLocation.Default;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the effect rendering order. Registered post effects are sorted before rendering (from the lowest order to the highest order).
|
||||
/// </summary>
|
||||
public virtual int Order => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Performs custom postFx rendering.
|
||||
/// </summary>
|
||||
/// <param name="context">The GPU commands context.</param>
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
/// <param name="input">The input texture.</param>
|
||||
/// <param name="output">The output texture.</param>
|
||||
public abstract void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output);
|
||||
|
||||
internal static void FetchInfo(PostProcessEffect obj, out PostProcessEffectLocation location, out bool useSingleTarget)
|
||||
{
|
||||
location = obj.Location;
|
||||
useSingleTarget = obj.UseSingleTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Enums.h"
|
||||
|
||||
class RenderTask;
|
||||
class GPUTexture;
|
||||
class GPUTextureView;
|
||||
struct RenderContext;
|
||||
|
||||
/// <summary>
|
||||
/// Post process effects base class.
|
||||
/// </summary>
|
||||
class PostProcessBase
|
||||
{
|
||||
protected:
|
||||
bool _isEnabled;
|
||||
bool _useSingleTarget;
|
||||
PostProcessEffectLocation _location;
|
||||
|
||||
PostProcessBase()
|
||||
: _isEnabled(true)
|
||||
, _useSingleTarget(false)
|
||||
, _location(PostProcessEffectLocation::Default)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Destructor
|
||||
/// </summary>
|
||||
virtual ~PostProcessBase()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Returns true if effect is enabled
|
||||
/// </summary>
|
||||
/// <returns>True if is enabled, otherwise false</returns>
|
||||
bool IsEnabled() const
|
||||
{
|
||||
return _isEnabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set enabled state
|
||||
/// </summary>
|
||||
/// <param name="enabled">True if enable, otherwise disable effect</param>
|
||||
virtual void SetEnabled(bool enabled)
|
||||
{
|
||||
// Check if value will change
|
||||
if (_isEnabled != enabled)
|
||||
{
|
||||
// Change value
|
||||
_isEnabled = enabled;
|
||||
|
||||
// Fire events
|
||||
if (_isEnabled)
|
||||
onEnable();
|
||||
else
|
||||
onDisable();
|
||||
onEnabledChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if effect is loaded and can be rendered
|
||||
/// </summary>
|
||||
/// <returns>True if is loaded</returns>
|
||||
virtual bool IsLoaded() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if effect is ready for rendering
|
||||
/// </summary>
|
||||
/// <returns>True if is ready</returns>
|
||||
bool IsReady() const
|
||||
{
|
||||
return _isEnabled && IsLoaded();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether use a single render target as both input and output. Use this if your effect doesn't need to copy the input buffer to the output but can render directly to the single texture. Can be used to optimize game performance.
|
||||
/// </summary>
|
||||
bool GetUseSingleTarget() const
|
||||
{
|
||||
return _useSingleTarget;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the effect rendering location within rendering pipeline.
|
||||
/// </summary>
|
||||
/// <returns>Render location.</returns>
|
||||
PostProcessEffectLocation GetLocation() const
|
||||
{
|
||||
return _location;
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Perform rendering
|
||||
/// </summary>
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
/// <param name="input">The input texture.</param>
|
||||
/// <param name="output">The output texture.</param>
|
||||
virtual void Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output) = 0;
|
||||
|
||||
protected:
|
||||
virtual void onEnable()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void onDisable()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void onEnabledChanged()
|
||||
{
|
||||
}
|
||||
};
|
||||
57
Source/Engine/Graphics/PostProcessEffect.h
Normal file
57
Source/Engine/Graphics/PostProcessEffect.h
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Scripting/Script.h"
|
||||
#include "Enums.h"
|
||||
|
||||
class GPUTexture;
|
||||
class GPUContext;
|
||||
struct RenderContext;
|
||||
|
||||
/// <summary>
|
||||
/// Custom PostFx which can modify final image by processing it with material based filters. The base class for all post process effects used by the graphics pipeline. Allows to extend frame rendering logic and apply custom effects such as outline, night vision, contrast etc.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Override this class and implement custom post fx logic. Use <b>MainRenderTask.Instance.CustomPostFx.Add(myPostFx)</b> to attach your script to rendering or add script to camera actor.
|
||||
/// </remarks>
|
||||
API_CLASS(Abstract) class FLAXENGINE_API PostProcessEffect : public Script
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE(PostProcessEffect);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Effect rendering location within rendering pipeline.
|
||||
/// </summary>
|
||||
API_FIELD() PostProcessEffectLocation Location = PostProcessEffectLocation::Default;
|
||||
|
||||
/// <summary>
|
||||
/// True whether use a single render target as both input and output. Use this if your effect doesn't need to copy the input buffer to the output but can render directly to the single texture. Can be used to optimize game performance.
|
||||
/// </summary>
|
||||
API_FIELD() bool UseSingleTarget = false;
|
||||
|
||||
/// <summary>
|
||||
/// Effect rendering order. Post effects are sorted before rendering (from the lowest order to the highest order).
|
||||
/// </summary>
|
||||
API_FIELD() int32 Order = 0;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this effect can be rendered.
|
||||
/// </summary>
|
||||
API_FUNCTION() virtual bool CanRender() const
|
||||
{
|
||||
return GetEnabled();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs custom postFx rendering.
|
||||
/// </summary>
|
||||
/// <param name="context">The GPU commands context.</param>
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
/// <param name="input">The input texture.</param>
|
||||
/// <param name="output">The output texture.</param>
|
||||
API_FUNCTION() virtual void Render(GPUContext* context, API_PARAM(Ref) RenderContext& renderContext, GPUTexture* input, GPUTexture* output)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "RenderBuffers.h"
|
||||
#include "GPUDevice.h"
|
||||
#include "GPUSwapChain.h"
|
||||
#include "FlaxEngine.Gen.h"
|
||||
#include "PostProcessEffect.h"
|
||||
#include "Engine/Core/Collections/Sorting.h"
|
||||
#include "Engine/Debug/DebugLog.h"
|
||||
#include "Engine/Level/Level.h"
|
||||
@@ -14,55 +14,25 @@
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Level/Actors/PostFxVolume.h"
|
||||
#include "Engine/Profiler/Profiler.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MAssembly.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MMethod.h"
|
||||
#include "Engine/Scripting/Script.h"
|
||||
#include "Engine/Scripting/BinaryModule.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#if USE_MONO
|
||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||
#endif
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Renderer/Lightmaps.h"
|
||||
#else
|
||||
#include "Engine/Engine/Screen.h"
|
||||
#endif
|
||||
|
||||
#if USE_MONO
|
||||
|
||||
// TODO: use API for events and remove this manual wrapper code
|
||||
struct RenderContextManaged
|
||||
{
|
||||
MonoObject* Buffers;
|
||||
MonoObject* List;
|
||||
MonoObject* Task;
|
||||
RenderView* LodProxyView;
|
||||
RenderView View;
|
||||
};
|
||||
|
||||
// TODO: use API for events and remove this manual wrapper code
|
||||
namespace
|
||||
{
|
||||
RenderContextManaged ToManaged(const RenderContext& value)
|
||||
{
|
||||
RenderContextManaged result;
|
||||
result.Buffers = ScriptingObject::ToManaged((ScriptingObject*)value.Buffers);
|
||||
result.List = ScriptingObject::ToManaged((ScriptingObject*)value.List);
|
||||
result.Task = ScriptingObject::ToManaged((ScriptingObject*)value.Task);
|
||||
result.LodProxyView = value.LodProxyView;
|
||||
result.View = value.View;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Array<RenderTask*> RenderTask::Tasks;
|
||||
CriticalSection RenderTask::TasksLocker;
|
||||
int32 RenderTask::TasksDoneLastFrame;
|
||||
Array<PostProcessEffect*> SceneRenderTask::GlobalCustomPostFx;
|
||||
MainRenderTask* MainRenderTask::Instance;
|
||||
|
||||
PostProcessEffect::PostProcessEffect(const SpawnParams& params)
|
||||
: Script(params)
|
||||
{
|
||||
}
|
||||
|
||||
void RenderTask::DrawAll()
|
||||
{
|
||||
ScopeLock lock(TasksLocker);
|
||||
@@ -160,62 +130,6 @@ bool RenderTask::Resize(int32 width, int32 height)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ManagedPostProcessEffect::FetchInfo()
|
||||
{
|
||||
ASSERT(Target);
|
||||
|
||||
SetEnabled(Target->GetEnabled());
|
||||
|
||||
static MMethod* FetchInfoManaged = nullptr;
|
||||
if (FetchInfoManaged == nullptr)
|
||||
{
|
||||
auto klass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEngine.PostProcessEffect");
|
||||
ASSERT(klass);
|
||||
FetchInfoManaged = klass->GetMethod("FetchInfo", 3);
|
||||
ASSERT(FetchInfoManaged);
|
||||
}
|
||||
|
||||
void* args[3];
|
||||
args[0] = Target->GetOrCreateManagedInstance();
|
||||
args[1] = &_location;
|
||||
args[2] = &_useSingleTarget;
|
||||
MObject* exception = nullptr;
|
||||
FetchInfoManaged->Invoke(nullptr, args, &exception);
|
||||
if (exception)
|
||||
DebugLog::LogException(exception);
|
||||
}
|
||||
|
||||
bool ManagedPostProcessEffect::IsLoaded() const
|
||||
{
|
||||
return Target != nullptr;
|
||||
}
|
||||
|
||||
void ManagedPostProcessEffect::Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output)
|
||||
{
|
||||
#if USE_MONO
|
||||
const auto context = GPUDevice::Instance->GetMainContext();
|
||||
auto inputObj = ScriptingObject::ToManaged(input);
|
||||
auto outputObj = ScriptingObject::ToManaged(output);
|
||||
|
||||
// Call rendering method (handle base classes)
|
||||
ASSERT(Target && Target->GetClass() != nullptr);
|
||||
auto mclass = Target->GetClass();
|
||||
auto renderMethod = mclass->FindMethod("Render", 4, true);
|
||||
if (renderMethod == nullptr)
|
||||
return;
|
||||
RenderContextManaged tmp = ::ToManaged(renderContext);
|
||||
void* params[4];
|
||||
params[0] = context->GetOrCreateManagedInstance();
|
||||
params[1] = &tmp;
|
||||
params[2] = inputObj;
|
||||
params[3] = outputObj;
|
||||
MObject* exception = nullptr;
|
||||
renderMethod->InvokeVirtual(Target->GetOrCreateManagedInstance(), params, &exception);
|
||||
if (exception)
|
||||
DebugLog::LogException(exception);
|
||||
#endif
|
||||
}
|
||||
|
||||
SceneRenderTask::SceneRenderTask(const SpawnParams& params)
|
||||
: RenderTask(params)
|
||||
{
|
||||
@@ -252,6 +166,26 @@ void SceneRenderTask::ClearCustomActors()
|
||||
CustomActors.Clear();
|
||||
}
|
||||
|
||||
void SceneRenderTask::AddCustomPostFx(PostProcessEffect* fx)
|
||||
{
|
||||
CustomPostFx.Add(fx);
|
||||
}
|
||||
|
||||
void SceneRenderTask::RemoveCustomPostFx(PostProcessEffect* fx)
|
||||
{
|
||||
CustomPostFx.Remove(fx);
|
||||
}
|
||||
|
||||
void SceneRenderTask::AddGlobalCustomPostFx(PostProcessEffect* fx)
|
||||
{
|
||||
GlobalCustomPostFx.Add(fx);
|
||||
}
|
||||
|
||||
void SceneRenderTask::RemoveGlobalCustomPostFx(PostProcessEffect* fx)
|
||||
{
|
||||
GlobalCustomPostFx.Remove(fx);
|
||||
}
|
||||
|
||||
void SceneRenderTask::CollectPostFxVolumes(RenderContext& renderContext)
|
||||
{
|
||||
// Cache WorldPosition used for PostFx volumes blending (RenderView caches it later on)
|
||||
@@ -263,7 +197,7 @@ void SceneRenderTask::CollectPostFxVolumes(RenderContext& renderContext)
|
||||
}
|
||||
if ((ActorsSource & ActorsSources::CustomActors) != 0)
|
||||
{
|
||||
for (auto a : CustomActors)
|
||||
for (Actor* a : CustomActors)
|
||||
{
|
||||
auto* postFxVolume = dynamic_cast<PostFxVolume*>(a);
|
||||
if (postFxVolume && a->GetIsActive())
|
||||
@@ -285,8 +219,47 @@ void AddActorToSceneRendering(SceneRendering* s, Actor* a)
|
||||
}
|
||||
}
|
||||
|
||||
bool SortPostFx(PostProcessEffect* const& a, PostProcessEffect* const& b)
|
||||
{
|
||||
return a->Order < b->Order;
|
||||
}
|
||||
|
||||
void SceneRenderTask::OnCollectDrawCalls(RenderContextBatch& renderContextBatch, byte category)
|
||||
{
|
||||
// Setup PostFx in the render list
|
||||
if (category == SceneRendering::DrawCategory::PreRender)
|
||||
{
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
auto& postFx = renderContext.List->PostFx;
|
||||
|
||||
// Collect all post effects
|
||||
if (AllowGlobalCustomPostFx)
|
||||
{
|
||||
for (PostProcessEffect* fx : GlobalCustomPostFx)
|
||||
{
|
||||
if (fx && fx->CanRender())
|
||||
postFx.Add(fx);
|
||||
}
|
||||
}
|
||||
for (PostProcessEffect* fx : CustomPostFx)
|
||||
{
|
||||
if (fx && fx->CanRender())
|
||||
postFx.Add(fx);
|
||||
}
|
||||
if (const auto* camera = Camera.Get())
|
||||
{
|
||||
for (Script* script : camera->Scripts)
|
||||
{
|
||||
auto* fx = Cast<PostProcessEffect>(script);
|
||||
if (fx && fx->CanRender())
|
||||
postFx.Add(fx);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by order
|
||||
Sorting::QuickSort(postFx.Get(), postFx.Count(), &SortPostFx);
|
||||
}
|
||||
|
||||
// Draw actors (collect draw calls)
|
||||
if ((ActorsSource & ActorsSources::CustomActors) != 0)
|
||||
{
|
||||
@@ -373,33 +346,6 @@ void SceneRenderTask::OnBegin(GPUContext* context)
|
||||
View.CopyFrom(Camera, &viewport);
|
||||
}
|
||||
|
||||
// Get custom and global PostFx
|
||||
CustomPostFx.Clear();
|
||||
#if !COMPILE_WITHOUT_CSHARP
|
||||
// TODO: move postFx in SceneRenderTask from C# to C++
|
||||
static MMethod* GetPostFxManaged = GetStaticClass()->GetMethod("GetPostFx", 1);
|
||||
if (GetPostFxManaged)
|
||||
{
|
||||
int32 count = 0;
|
||||
void* params[1];
|
||||
params[0] = &count;
|
||||
MObject* exception = nullptr;
|
||||
#if USE_MONO
|
||||
const auto objects = (MonoArray*)GetPostFxManaged->Invoke(GetOrCreateManagedInstance(), params, &exception);
|
||||
if (exception)
|
||||
DebugLog::LogException(exception);
|
||||
CustomPostFx.Resize(count);
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
auto& postFx = CustomPostFx[i];
|
||||
postFx.Target = mono_array_get(objects, Script*, i);
|
||||
if (postFx.Target)
|
||||
postFx.FetchInfo();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Setup render buffers for the output rendering resolution
|
||||
if (Output)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
partial class RenderTask
|
||||
@@ -42,72 +39,5 @@ namespace FlaxEngine
|
||||
View = view;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The global custom post processing effects applied to all <see cref="SceneRenderTask"/> (applied to tasks that have <see cref="AllowGlobalCustomPostFx"/> turned on).
|
||||
/// </summary>
|
||||
public static readonly HashSet<PostProcessEffect> GlobalCustomPostFx = new HashSet<PostProcessEffect>();
|
||||
|
||||
/// <summary>
|
||||
/// The custom post processing effects.
|
||||
/// </summary>
|
||||
public readonly HashSet<PostProcessEffect> CustomPostFx = new HashSet<PostProcessEffect>();
|
||||
|
||||
/// <summary>
|
||||
/// True if allow using global custom PostFx when rendering this task.
|
||||
/// </summary>
|
||||
public bool AllowGlobalCustomPostFx = true;
|
||||
|
||||
private static List<PostProcessEffect> _postFx;
|
||||
private static IntPtr[] _postFxPtr;
|
||||
private static Comparison<PostProcessEffect> _postFxComparison = (x, y) => x.Order - y.Order;
|
||||
|
||||
internal IntPtr[] GetPostFx(out int count)
|
||||
{
|
||||
if (_postFx == null)
|
||||
_postFx = new List<PostProcessEffect>();
|
||||
|
||||
// Get custom post effects to render (registered ones and from the current camera)
|
||||
|
||||
foreach (var postFx in CustomPostFx)
|
||||
{
|
||||
if (postFx.CanRender)
|
||||
_postFx.Add(postFx);
|
||||
}
|
||||
if (AllowGlobalCustomPostFx)
|
||||
{
|
||||
foreach (var postFx in GlobalCustomPostFx)
|
||||
{
|
||||
if (postFx.CanRender)
|
||||
_postFx.Add(postFx);
|
||||
}
|
||||
}
|
||||
var camera = Camera;
|
||||
if (camera != null)
|
||||
{
|
||||
var perCameraPostFx = camera.GetScripts<PostProcessEffect>();
|
||||
for (int i = 0; i < perCameraPostFx.Length; i++)
|
||||
{
|
||||
var postFx = perCameraPostFx[i];
|
||||
if (postFx.CanRender)
|
||||
_postFx.Add(postFx);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort postFx
|
||||
_postFx.Sort(_postFxComparison);
|
||||
|
||||
// Convert into unmanaged objects
|
||||
count = _postFx.Count;
|
||||
if (_postFxPtr == null || _postFxPtr.Length < count)
|
||||
_postFxPtr = new IntPtr[_postFx.Capacity];
|
||||
for (int i = 0; i < count; i++)
|
||||
_postFxPtr[i] = GetUnmanagedPtr(_postFx[i]);
|
||||
|
||||
// Release references to managed objects
|
||||
_postFx.Clear();
|
||||
|
||||
return _postFxPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "Engine/Scripting/ScriptingObjectReference.h"
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
#include "Engine/Renderer/RendererAllocation.h"
|
||||
#include "PostProcessBase.h"
|
||||
#include "RenderView.h"
|
||||
|
||||
class GPUDevice;
|
||||
@@ -18,6 +17,7 @@ class GPUTexture;
|
||||
class GPUTextureView;
|
||||
class GPUSwapChain;
|
||||
class RenderBuffers;
|
||||
class PostProcessEffect;
|
||||
struct RenderContext;
|
||||
class Camera;
|
||||
class Actor;
|
||||
@@ -182,31 +182,6 @@ API_ENUM(Attributes="Flags") enum class ActorsSources
|
||||
|
||||
DECLARE_ENUM_OPERATORS(ActorsSources);
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper for PostProcessBase that allows to render to customized managed postFx.
|
||||
/// TODO: add support for managed inheritance of custom native types with proper spawn handling (like for ManagedScript)
|
||||
/// </summary>
|
||||
/// <seealso cref="PostProcessBase" />
|
||||
class ManagedPostProcessEffect : public PostProcessBase
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// The script to use. Inherits from C# class 'PostProcessEffect'.
|
||||
/// </summary>
|
||||
Script* Target = nullptr;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Fetches the information about the PostFx location from the managed object.
|
||||
/// </summary>
|
||||
void FetchInfo();
|
||||
|
||||
public:
|
||||
// [PostProcessBase]
|
||||
bool IsLoaded() const override;
|
||||
void Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output) override;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Render task which draws scene actors into the output buffer.
|
||||
/// </summary>
|
||||
@@ -269,6 +244,7 @@ public:
|
||||
/// </summary>
|
||||
API_FIELD() float RenderingPercentage = 1.0f;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The custom set of actors to render.
|
||||
/// </summary>
|
||||
@@ -291,10 +267,45 @@ public:
|
||||
/// </summary>
|
||||
API_FUNCTION() void ClearCustomActors();
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The custom post fx to render (managed).
|
||||
/// The custom set of postfx to render.
|
||||
/// </summary>
|
||||
Array<ManagedPostProcessEffect> CustomPostFx;
|
||||
Array<PostProcessEffect*> CustomPostFx;
|
||||
|
||||
/// <summary>
|
||||
/// Adds the custom postfx to the rendering.
|
||||
/// </summary>
|
||||
/// <param name="fx">The postfx script.</param>
|
||||
API_FUNCTION() void AddCustomPostFx(PostProcessEffect* fx);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the custom postfx from the rendering.
|
||||
/// </summary>
|
||||
/// <param name="fx">The postfx script.</param>
|
||||
API_FUNCTION() void RemoveCustomPostFx(PostProcessEffect* fx);
|
||||
|
||||
/// <summary>
|
||||
/// True if allow using global custom PostFx when rendering this task.
|
||||
/// </summary>
|
||||
API_FIELD() bool AllowGlobalCustomPostFx = true;
|
||||
|
||||
/// <summary>
|
||||
/// The custom set of global postfx to render for all <see cref="SceneRenderTask"/> (applied to tasks that have <see cref="AllowGlobalCustomPostFx"/> turned on).
|
||||
/// </summary>
|
||||
static Array<PostProcessEffect*> GlobalCustomPostFx;
|
||||
|
||||
/// <summary>
|
||||
/// Adds the custom global postfx to the rendering.
|
||||
/// </summary>
|
||||
/// <param name="fx">The postfx script.</param>
|
||||
API_FUNCTION() static void AddGlobalCustomPostFx(PostProcessEffect* fx);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the custom global postfx from the rendering.
|
||||
/// </summary>
|
||||
/// <param name="fx">The postfx script.</param>
|
||||
API_FUNCTION() static void RemoveGlobalCustomPostFx(PostProcessEffect* fx);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/GPULimits.h"
|
||||
#include "Engine/Graphics/PostProcessBase.h"
|
||||
#include "Engine/Graphics/Shaders/GPUShader.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/RenderTargetPool.h"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "RenderList.h"
|
||||
#include "Engine/Content/Assets/Shader.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Graphics/PostProcessBase.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/RenderBuffers.h"
|
||||
#include "Engine/Graphics/GPULimits.h"
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
#include "RenderList.h"
|
||||
#include "Engine/Content/Assets/Shader.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Graphics/PostProcessBase.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/RenderBuffers.h"
|
||||
#include "Engine/Graphics/RenderTargetPool.h"
|
||||
#include "Engine/Engine/Time.h"
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/PostProcessBase.h"
|
||||
#include "Engine/Graphics/GPULimits.h"
|
||||
#include "Engine/Graphics/RenderTargetPool.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Graphics/Graphics.h"
|
||||
#include "Engine/Graphics/PostProcessEffect.h"
|
||||
#include "Engine/Profiler/Profiler.h"
|
||||
#include "Engine/Content/Assets/CubeTexture.h"
|
||||
#include "Engine/Graphics/Graphics.h"
|
||||
#include "Engine/Level/Scene/Lightmap.h"
|
||||
#include "Engine/Level/Actors/PostFxVolume.h"
|
||||
|
||||
@@ -220,13 +220,12 @@ void RenderList::RunPostFxPass(GPUContext* context, RenderContext& renderContext
|
||||
}
|
||||
if (renderContext.View.Flags & ViewFlags::CustomPostProcess)
|
||||
{
|
||||
for (int32 i = 0; i < renderContext.List->PostFx.Count(); i++)
|
||||
for (const PostProcessEffect* fx : renderContext.List->PostFx)
|
||||
{
|
||||
const auto fx = renderContext.List->PostFx[i];
|
||||
if (fx->IsReady() && fx->GetLocation() == locationB)
|
||||
if (fx->Location == locationB)
|
||||
{
|
||||
skipPass = false;
|
||||
needTempTarget |= !fx->GetUseSingleTarget();
|
||||
needTempTarget |= !fx->UseSingleTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,19 +257,18 @@ void RenderList::RunPostFxPass(GPUContext* context, RenderContext& renderContext
|
||||
}
|
||||
if (renderContext.View.Flags & ViewFlags::CustomPostProcess)
|
||||
{
|
||||
for (int32 i = 0; i < renderContext.List->PostFx.Count(); i++)
|
||||
for (PostProcessEffect* fx : renderContext.List->PostFx)
|
||||
{
|
||||
auto fx = renderContext.List->PostFx[i];
|
||||
if (fx->IsReady() && fx->GetLocation() == locationB)
|
||||
if (fx->Location == locationB)
|
||||
{
|
||||
if (fx->GetUseSingleTarget())
|
||||
if (fx->UseSingleTarget)
|
||||
{
|
||||
fx->Render(renderContext, input, nullptr);
|
||||
fx->Render(context, renderContext, input, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(needTempTarget);
|
||||
fx->Render(renderContext, input, output);
|
||||
fx->Render(context, renderContext, input, output);
|
||||
Swap(input, output);
|
||||
}
|
||||
context->ResetRenderTarget();
|
||||
@@ -306,19 +304,17 @@ void RenderList::RunCustomPostFxPass(GPUContext* context, RenderContext& renderC
|
||||
{
|
||||
if (!(renderContext.View.Flags & ViewFlags::CustomPostProcess))
|
||||
return;
|
||||
|
||||
for (int32 i = 0; i < renderContext.List->PostFx.Count(); i++)
|
||||
for (PostProcessEffect* fx : renderContext.List->PostFx)
|
||||
{
|
||||
auto fx = renderContext.List->PostFx[i];
|
||||
if (fx->IsReady() && fx->GetLocation() == location)
|
||||
if (fx->Location == location)
|
||||
{
|
||||
if (fx->GetUseSingleTarget())
|
||||
if (fx->UseSingleTarget)
|
||||
{
|
||||
fx->Render(renderContext, input, nullptr);
|
||||
fx->Render(context, renderContext, input, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
fx->Render(renderContext, input, output);
|
||||
fx->Render(context, renderContext, input, output);
|
||||
Swap(input, output);
|
||||
}
|
||||
context->ResetRenderTarget();
|
||||
@@ -330,13 +326,10 @@ bool RenderList::HasAnyPostFx(const RenderContext& renderContext, PostProcessEff
|
||||
{
|
||||
if (renderContext.View.Flags & ViewFlags::CustomPostProcess)
|
||||
{
|
||||
for (int32 i = 0; i < renderContext.List->PostFx.Count(); i++)
|
||||
for (const PostProcessEffect* fx : renderContext.List->PostFx)
|
||||
{
|
||||
auto fx = renderContext.List->PostFx[i];
|
||||
if (fx->IsReady() && fx->GetLocation() == postProcess)
|
||||
{
|
||||
if (fx->Location == postProcess)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
|
||||
enum class StaticFlags;
|
||||
class RenderBuffers;
|
||||
class PostProcessEffect;
|
||||
class SceneRendering;
|
||||
class LightWithShadow;
|
||||
class IPostFxSettingsProvider;
|
||||
class CubeTexture;
|
||||
class PostProcessBase;
|
||||
struct RenderContext;
|
||||
|
||||
struct RendererDirectionalLightData
|
||||
@@ -352,9 +352,9 @@ public:
|
||||
IFogRenderer* Fog;
|
||||
|
||||
/// <summary>
|
||||
/// Post effect to render (TEMPORARY! cleared after and before rendering).
|
||||
/// Post effects to render.
|
||||
/// </summary>
|
||||
Array<PostProcessBase*> PostFx;
|
||||
Array<PostProcessEffect*> PostFx;
|
||||
|
||||
/// <summary>
|
||||
/// The post process settings.
|
||||
|
||||
@@ -315,11 +315,6 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
|
||||
if (renderContext.View.Origin != renderContext.View.PrevOrigin)
|
||||
renderContext.Task->CameraCut(); // Cut any temporal effects on rendering origin change
|
||||
renderContext.Buffers->Prepare();
|
||||
for (auto& postFx : task->CustomPostFx)
|
||||
{
|
||||
if (postFx.Target)
|
||||
renderContext.List->PostFx.Add(&postFx);
|
||||
}
|
||||
|
||||
// Build batch of render contexts (main view and shadow projections)
|
||||
const bool isGBufferDebug = GBufferPass::IsDebugView(renderContext.View.Mode);
|
||||
|
||||
@@ -48,13 +48,20 @@ namespace FlaxEngine
|
||||
public UICanvas Canvas;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool UseSingleTarget => true;
|
||||
public CanvasRenderer()
|
||||
{
|
||||
UseSingleTarget = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override PostProcessEffectLocation Location => Canvas.RenderLocation;
|
||||
public override bool CanRender()
|
||||
{
|
||||
// Sync with canvas options
|
||||
Location = Canvas.RenderLocation;
|
||||
Order = Canvas.Order;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Order => Canvas.Order;
|
||||
return base.CanRender();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
|
||||
@@ -486,9 +493,9 @@ namespace FlaxEngine
|
||||
if (_renderer)
|
||||
{
|
||||
#if FLAX_EDITOR
|
||||
_editorTask?.CustomPostFx.Remove(_renderer);
|
||||
_editorTask?.RemoveCustomPostFx(_renderer);
|
||||
#endif
|
||||
SceneRenderTask.GlobalCustomPostFx.Remove(_renderer);
|
||||
SceneRenderTask.RemoveGlobalCustomPostFx(_renderer);
|
||||
_renderer.Canvas = null;
|
||||
Destroy(_renderer);
|
||||
_renderer = null;
|
||||
@@ -526,16 +533,16 @@ namespace FlaxEngine
|
||||
#if FLAX_EDITOR
|
||||
if (_editorTask != null)
|
||||
{
|
||||
_editorTask.CustomPostFx.Add(_renderer);
|
||||
_editorTask.AddCustomPostFx(_renderer);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
SceneRenderTask.GlobalCustomPostFx.Add(_renderer);
|
||||
SceneRenderTask.AddGlobalCustomPostFx(_renderer);
|
||||
}
|
||||
#if FLAX_EDITOR
|
||||
else if (_editorTask != null && IsActiveInHierarchy)
|
||||
{
|
||||
_editorTask.CustomPostFx.Add(_renderer);
|
||||
_editorTask.AddCustomPostFx(_renderer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -777,11 +784,11 @@ namespace FlaxEngine
|
||||
#if FLAX_EDITOR
|
||||
if (_editorTask != null)
|
||||
{
|
||||
_editorTask.CustomPostFx.Add(_renderer);
|
||||
_editorTask.AddCustomPostFx(_renderer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
SceneRenderTask.GlobalCustomPostFx.Add(_renderer);
|
||||
SceneRenderTask.AddGlobalCustomPostFx(_renderer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,7 +798,7 @@ namespace FlaxEngine
|
||||
|
||||
if (_renderer)
|
||||
{
|
||||
SceneRenderTask.GlobalCustomPostFx.Remove(_renderer);
|
||||
SceneRenderTask.RemoveGlobalCustomPostFx(_renderer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -816,7 +823,7 @@ namespace FlaxEngine
|
||||
|
||||
if (_renderer)
|
||||
{
|
||||
SceneRenderTask.GlobalCustomPostFx.Remove(_renderer);
|
||||
SceneRenderTask.RemoveGlobalCustomPostFx(_renderer);
|
||||
_renderer.Canvas = null;
|
||||
Destroy(_renderer);
|
||||
_renderer = null;
|
||||
@@ -832,7 +839,7 @@ namespace FlaxEngine
|
||||
if (_editorTask == task && _editorRoot == root)
|
||||
return;
|
||||
if (_editorTask != null && _renderer != null)
|
||||
_editorTask.CustomPostFx.Remove(_renderer);
|
||||
_editorTask.RemoveCustomPostFx(_renderer);
|
||||
if (_editorRoot != null && _guiRoot != null)
|
||||
_guiRoot.Parent = null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user