Refactor scene rendering to separate drawable actors
This commit is contained in:
@@ -718,16 +718,17 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
|
||||
if (renderContext.Buffers == nullptr || !DebugDrawVB)
|
||||
return;
|
||||
auto context = GPUDevice::Instance->GetMainContext();
|
||||
if (Context->Origin != renderContext.View.Origin)
|
||||
const RenderView& view = renderContext.View;
|
||||
if (Context->Origin != view.Origin)
|
||||
{
|
||||
// Teleport existing debug shapes to maintain their location
|
||||
Float3 delta = Context->Origin - renderContext.View.Origin;
|
||||
Float3 delta = Context->Origin - view.Origin;
|
||||
Context->DebugDrawDefault.Teleport(delta);
|
||||
Context->DebugDrawDepthTest.Teleport(delta);
|
||||
Context->Origin = renderContext.View.Origin;
|
||||
Context->Origin = view.Origin;
|
||||
}
|
||||
Context->LastViewPos = renderContext.View.Position;
|
||||
Context->LastViewProj = renderContext.View.Projection;
|
||||
Context->LastViewPos = view.Position;
|
||||
Context->LastViewProj = view.Projection;
|
||||
|
||||
// Fallback to task buffers
|
||||
if (target == nullptr && renderContext.Task)
|
||||
@@ -755,7 +756,7 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
|
||||
const auto cb = DebugDrawShader->GetShader()->GetCB(0);
|
||||
Data data;
|
||||
Matrix vp;
|
||||
Matrix::Multiply(renderContext.View.View, renderContext.View.NonJitteredProjection, vp);
|
||||
Matrix::Multiply(view.View, view.NonJitteredProjection, vp);
|
||||
Matrix::Transpose(vp, data.ViewProjection);
|
||||
data.EnableDepthTest = enableDepthTest;
|
||||
context->UpdateCB(cb, &data);
|
||||
@@ -866,7 +867,7 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
|
||||
Matrix f;
|
||||
Matrix::RotationZ(PI, f);
|
||||
Float3 viewUp;
|
||||
Float3::Transform(Float3::Up, Quaternion::LookRotation(renderContext.View.Direction, Float3::Up), viewUp);
|
||||
Float3::Transform(Float3::Up, Quaternion::LookRotation(view.Direction, Float3::Up), viewUp);
|
||||
for (auto& t : Context->DebugDrawDefault.DefaultText3D)
|
||||
DrawText3D(t, renderContext, viewUp, f, vp, viewport, context, target, nullptr);
|
||||
for (auto& t : Context->DebugDrawDefault.OneFrameText3D)
|
||||
|
||||
@@ -43,7 +43,7 @@ void VolumeParticleMaterialShader::Bind(BindParameters& params)
|
||||
{
|
||||
// Prepare
|
||||
auto context = params.GPUContext;
|
||||
auto& view = params.RenderContext.View;
|
||||
const RenderView& view = params.RenderContext.View;
|
||||
auto& drawCall = *params.FirstDrawCall;
|
||||
Span<byte> cb(_cbData.Get(), _cbData.Count());
|
||||
ASSERT_LOW_LAYER(cb.Length() >= sizeof(VolumeParticleMaterialShaderData));
|
||||
|
||||
@@ -32,27 +32,26 @@
|
||||
#if USE_MONO
|
||||
|
||||
// TODO: use API for events and remove this manual wrapper code
|
||||
class RenderContextInternal
|
||||
struct RenderContextManaged
|
||||
{
|
||||
public:
|
||||
MonoObject* Buffers;
|
||||
MonoObject* List;
|
||||
RenderView View;
|
||||
RenderView* LodProxyView;
|
||||
MonoObject* Task;
|
||||
RenderView* LodProxyView;
|
||||
RenderView View;
|
||||
};
|
||||
|
||||
// TODO: use API for events and remove this manual wrapper code
|
||||
namespace
|
||||
{
|
||||
RenderContextInternal ToManaged(const RenderContext& value)
|
||||
RenderContextManaged ToManaged(const RenderContext& value)
|
||||
{
|
||||
RenderContextInternal result;
|
||||
RenderContextManaged result;
|
||||
result.Buffers = ScriptingObject::ToManaged((ScriptingObject*)value.Buffers);
|
||||
result.List = ScriptingObject::ToManaged((ScriptingObject*)value.List);
|
||||
result.View = value.View;
|
||||
result.LodProxyView = value.LodProxyView;
|
||||
result.Task = ScriptingObject::ToManaged((ScriptingObject*)value.Task);
|
||||
result.LodProxyView = value.LodProxyView;
|
||||
result.View = value.View;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -204,7 +203,7 @@ void ManagedPostProcessEffect::Render(RenderContext& renderContext, GPUTexture*
|
||||
auto renderMethod = mclass->FindMethod("Render", 4, true);
|
||||
if (renderMethod == nullptr)
|
||||
return;
|
||||
RenderContextInternal tmp = ::ToManaged(renderContext);
|
||||
RenderContextManaged tmp = ::ToManaged(renderContext);
|
||||
void* params[4];
|
||||
params[0] = context->GetOrCreateManagedInstance();
|
||||
params[1] = &tmp;
|
||||
@@ -286,7 +285,7 @@ void AddActorToSceneRendering(SceneRendering* s, Actor* a)
|
||||
}
|
||||
}
|
||||
|
||||
void SceneRenderTask::OnCollectDrawCalls(RenderContext& renderContext)
|
||||
void SceneRenderTask::OnCollectDrawCalls(RenderContext& renderContext, byte category)
|
||||
{
|
||||
// Draw actors (collect draw calls)
|
||||
if ((ActorsSource & ActorsSources::CustomActors) != 0)
|
||||
@@ -297,11 +296,11 @@ void SceneRenderTask::OnCollectDrawCalls(RenderContext& renderContext)
|
||||
_customActorsScene->Clear();
|
||||
for (Actor* a : CustomActors)
|
||||
AddActorToSceneRendering(_customActorsScene, a);
|
||||
_customActorsScene->Draw(renderContext);
|
||||
_customActorsScene->Draw(renderContext, (SceneRendering::DrawCategory)category);
|
||||
}
|
||||
if ((ActorsSource & ActorsSources::Scenes) != 0)
|
||||
{
|
||||
Level::DrawActors(renderContext);
|
||||
Level::DrawActors(renderContext, category);
|
||||
}
|
||||
|
||||
// External drawing event
|
||||
@@ -311,10 +310,18 @@ void SceneRenderTask::OnCollectDrawCalls(RenderContext& renderContext)
|
||||
void SceneRenderTask::OnPreRender(GPUContext* context, RenderContext& renderContext)
|
||||
{
|
||||
PreRender(context, renderContext);
|
||||
|
||||
// Collect initial draw calls
|
||||
renderContext.View.Pass = DrawPass::GBuffer;
|
||||
OnCollectDrawCalls(renderContext, SceneRendering::PreRender);
|
||||
}
|
||||
|
||||
void SceneRenderTask::OnPostRender(GPUContext* context, RenderContext& renderContext)
|
||||
{
|
||||
// Collect final draw calls
|
||||
renderContext.View.Pass = DrawPass::GBuffer;
|
||||
OnCollectDrawCalls(renderContext, SceneRendering::PostRender);
|
||||
|
||||
PostRender(context, renderContext);
|
||||
}
|
||||
|
||||
@@ -474,6 +481,6 @@ void MainRenderTask::OnBegin(GPUContext* context)
|
||||
RenderContext::RenderContext(SceneRenderTask* task)
|
||||
{
|
||||
Buffers = task->Buffers;
|
||||
View = task->View;
|
||||
Task = task;
|
||||
View = task->View;
|
||||
}
|
||||
|
||||
@@ -311,7 +311,8 @@ public:
|
||||
/// Calls drawing scene objects.
|
||||
/// </summary>
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
virtual void OnCollectDrawCalls(RenderContext& renderContext);
|
||||
/// <param name="category">The actors category to draw (see SceneRendering::DrawCategory).</param>
|
||||
virtual void OnCollectDrawCalls(RenderContext& renderContext, byte category = 0);
|
||||
|
||||
/// <summary>
|
||||
/// The action called after scene rendering. Can be used to perform custom pre-rendering or to modify the render view.
|
||||
@@ -394,7 +395,7 @@ public:
|
||||
/// <summary>
|
||||
/// The high-level renderer context. Used to collect the draw calls for the scene rendering. Can be used to perform a custom rendering.
|
||||
/// </summary>
|
||||
API_STRUCT() struct RenderContext
|
||||
API_STRUCT(NoDefault) struct RenderContext
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(RenderContext);
|
||||
|
||||
@@ -409,9 +410,9 @@ API_STRUCT() struct RenderContext
|
||||
API_FIELD() RenderList* List = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The render view.
|
||||
/// The scene rendering task that is a source of renderable objects (optional).
|
||||
/// </summary>
|
||||
API_FIELD() RenderView View;
|
||||
API_FIELD() SceneRenderTask* Task = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The proxy render view used to synchronize objects level of detail during rendering (eg. during shadow maps rendering passes). It's optional.
|
||||
@@ -419,9 +420,9 @@ API_STRUCT() struct RenderContext
|
||||
API_FIELD() RenderView* LodProxyView = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The scene rendering task that is a source of renderable objects (optional).
|
||||
/// The render view.
|
||||
/// </summary>
|
||||
API_FIELD() SceneRenderTask* Task = nullptr;
|
||||
API_FIELD() RenderView View;
|
||||
|
||||
RenderContext()
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ class SceneRenderTask;
|
||||
/// <summary>
|
||||
/// Rendering view description that defines how to render the objects (camera placement, rendering properties, etc.).
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API RenderView
|
||||
API_STRUCT(NoDefault) struct FLAXENGINE_API RenderView
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(RenderView);
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ BoundingBox Decal::GetEditorBox() const
|
||||
void Decal::OnLayerChanged()
|
||||
{
|
||||
if (_sceneRenderingKey != -1)
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
}
|
||||
|
||||
void Decal::Draw(RenderContext& renderContext)
|
||||
@@ -118,7 +118,7 @@ bool Decal::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal)
|
||||
|
||||
void Decal::OnEnable()
|
||||
{
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->AddViewportIcon(this);
|
||||
#endif
|
||||
@@ -132,7 +132,7 @@ void Decal::OnDisable()
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->RemoveViewportIcon(this);
|
||||
#endif
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
|
||||
// Base
|
||||
Actor::OnDisable();
|
||||
@@ -148,5 +148,5 @@ void Decal::OnTransformChanged()
|
||||
BoundingSphere::FromBox(_box, _sphere);
|
||||
|
||||
if (_sceneRenderingKey != -1)
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ bool DirectionalLight::IntersectsItself(const Ray& ray, Real& distance, Vector3&
|
||||
|
||||
void DirectionalLight::OnEnable()
|
||||
{
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->AddViewportIcon(this);
|
||||
#endif
|
||||
@@ -87,7 +87,7 @@ void DirectionalLight::OnDisable()
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->RemoveViewportIcon(this);
|
||||
#endif
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
|
||||
// Base
|
||||
LightWithShadow::OnDisable();
|
||||
|
||||
@@ -170,7 +170,7 @@ void EnvironmentProbe::UpdateBounds()
|
||||
_sphere = BoundingSphere(GetPosition(), GetScaledRadius());
|
||||
BoundingBox::FromSphere(_sphere, _box);
|
||||
if (_sceneRenderingKey != -1)
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
}
|
||||
|
||||
void EnvironmentProbe::Draw(RenderContext& renderContext)
|
||||
@@ -206,7 +206,7 @@ void EnvironmentProbe::OnDebugDrawSelected()
|
||||
void EnvironmentProbe::OnLayerChanged()
|
||||
{
|
||||
if (_sceneRenderingKey != -1)
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
}
|
||||
|
||||
void EnvironmentProbe::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
@@ -259,7 +259,7 @@ bool EnvironmentProbe::IntersectsItself(const Ray& ray, Real& distance, Vector3&
|
||||
|
||||
void EnvironmentProbe::OnEnable()
|
||||
{
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->AddViewportIcon(this);
|
||||
#endif
|
||||
@@ -273,7 +273,7 @@ void EnvironmentProbe::OnDisable()
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->RemoveViewportIcon(this);
|
||||
#endif
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
|
||||
// Base
|
||||
Actor::OnDisable();
|
||||
|
||||
@@ -209,7 +209,7 @@ void ExponentialHeightFog::DrawFog(GPUContext* context, RenderContext& renderCon
|
||||
|
||||
void ExponentialHeightFog::OnEnable()
|
||||
{
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->AddViewportIcon(this);
|
||||
#endif
|
||||
@@ -223,7 +223,7 @@ void ExponentialHeightFog::OnDisable()
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->RemoveViewportIcon(this);
|
||||
#endif
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
|
||||
// Base
|
||||
Actor::OnDisable();
|
||||
|
||||
@@ -66,12 +66,12 @@ void PointLight::UpdateBounds()
|
||||
BoundingBox::FromSphere(_sphere, _box);
|
||||
|
||||
if (_sceneRenderingKey != -1)
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
}
|
||||
|
||||
void PointLight::OnEnable()
|
||||
{
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->AddViewportIcon(this);
|
||||
#endif
|
||||
@@ -85,7 +85,7 @@ void PointLight::OnDisable()
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->RemoveViewportIcon(this);
|
||||
#endif
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
|
||||
// Base
|
||||
LightWithShadow::OnDisable();
|
||||
@@ -170,7 +170,7 @@ void PointLight::OnDebugDrawSelected()
|
||||
void PointLight::OnLayerChanged()
|
||||
{
|
||||
if (_sceneRenderingKey != -1)
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
}
|
||||
|
||||
void PointLight::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
|
||||
@@ -248,7 +248,7 @@ void Sky::EndPlay()
|
||||
|
||||
void Sky::OnEnable()
|
||||
{
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->AddViewportIcon(this);
|
||||
#endif
|
||||
@@ -262,7 +262,7 @@ void Sky::OnDisable()
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->RemoveViewportIcon(this);
|
||||
#endif
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
|
||||
// Base
|
||||
Actor::OnDisable();
|
||||
|
||||
@@ -181,7 +181,7 @@ bool SkyLight::HasContentLoaded() const
|
||||
|
||||
void SkyLight::OnEnable()
|
||||
{
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->AddViewportIcon(this);
|
||||
#endif
|
||||
@@ -195,7 +195,7 @@ void SkyLight::OnDisable()
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->RemoveViewportIcon(this);
|
||||
#endif
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
|
||||
// Base
|
||||
Light::OnDisable();
|
||||
|
||||
@@ -127,7 +127,7 @@ void Skybox::ApplySky(GPUContext* context, RenderContext& renderContext, const M
|
||||
|
||||
void Skybox::OnEnable()
|
||||
{
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->AddViewportIcon(this);
|
||||
#endif
|
||||
@@ -141,7 +141,7 @@ void Skybox::OnDisable()
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->RemoveViewportIcon(this);
|
||||
#endif
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
|
||||
// Base
|
||||
Actor::OnDisable();
|
||||
|
||||
@@ -114,12 +114,12 @@ void SpotLight::UpdateBounds()
|
||||
BoundingBox::FromSphere(_sphere, _box);
|
||||
|
||||
if (_sceneRenderingKey != -1)
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
}
|
||||
|
||||
void SpotLight::OnEnable()
|
||||
{
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->AddActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->AddViewportIcon(this);
|
||||
#endif
|
||||
@@ -133,7 +133,7 @@ void SpotLight::OnDisable()
|
||||
#if USE_EDITOR
|
||||
GetSceneRendering()->RemoveViewportIcon(this);
|
||||
#endif
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey);
|
||||
GetSceneRendering()->RemoveActor(this, _sceneRenderingKey, SceneRendering::PreRender);
|
||||
|
||||
// Base
|
||||
LightWithShadow::OnDisable();
|
||||
|
||||
@@ -389,7 +389,7 @@ void Level::CallBeginPlay(Actor* obj)
|
||||
}
|
||||
}
|
||||
|
||||
void Level::DrawActors(RenderContext& renderContext)
|
||||
void Level::DrawActors(RenderContext& renderContext, byte category)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
|
||||
@@ -398,7 +398,7 @@ void Level::DrawActors(RenderContext& renderContext)
|
||||
for (Scene* scene : Scenes)
|
||||
{
|
||||
if (scene->IsActiveInHierarchy())
|
||||
scene->Rendering.Draw(renderContext);
|
||||
scene->Rendering.Draw(renderContext, (SceneRendering::DrawCategory)category);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,8 @@ public:
|
||||
/// Draws all the actors.
|
||||
/// </summary>
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
static void DrawActors(RenderContext& renderContext);
|
||||
/// <param name="category">The actors category to draw (see SceneRendering::DrawCategory).</param>
|
||||
static void DrawActors(RenderContext& renderContext, byte category = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Collects all the post fx volumes.
|
||||
|
||||
@@ -28,20 +28,21 @@ void ISceneRenderingListener::ListenSceneRendering(SceneRendering* scene)
|
||||
}
|
||||
}
|
||||
|
||||
void SceneRendering::Draw(RenderContext& renderContext)
|
||||
void SceneRendering::Draw(RenderContext& renderContext, DrawCategory category)
|
||||
{
|
||||
ScopeLock lock(Locker);
|
||||
auto& view = renderContext.View;
|
||||
const BoundingFrustum frustum = view.CullingFrustum;
|
||||
const Vector3 origin = view.Origin;
|
||||
renderContext.List->Scenes.Add(this);
|
||||
auto& list = Actors[(int32)category];
|
||||
|
||||
// Draw all visual components
|
||||
if (view.IsOfflinePass)
|
||||
{
|
||||
for (int32 i = 0; i < Actors.Count(); i++)
|
||||
for (int32 i = 0; i < list.Count(); i++)
|
||||
{
|
||||
auto e = Actors.Get()[i];
|
||||
auto e = list.Get()[i];
|
||||
e.Bounds.Center -= origin;
|
||||
if (view.RenderLayersMask.Mask & e.LayerMask && (e.NoCulling || frustum.Intersects(e.Bounds)) && e.Actor->GetStaticFlags() & view.StaticFlagsMask)
|
||||
{
|
||||
@@ -54,9 +55,9 @@ void SceneRendering::Draw(RenderContext& renderContext)
|
||||
}
|
||||
else if (origin.IsZero())
|
||||
{
|
||||
for (int32 i = 0; i < Actors.Count(); i++)
|
||||
for (int32 i = 0; i < list.Count(); i++)
|
||||
{
|
||||
auto e = Actors.Get()[i];
|
||||
auto e = list.Get()[i];
|
||||
if (view.RenderLayersMask.Mask & e.LayerMask && (e.NoCulling || frustum.Intersects(e.Bounds)))
|
||||
{
|
||||
#if SCENE_RENDERING_USE_PROFILER
|
||||
@@ -68,9 +69,9 @@ void SceneRendering::Draw(RenderContext& renderContext)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int32 i = 0; i < Actors.Count(); i++)
|
||||
for (int32 i = 0; i < list.Count(); i++)
|
||||
{
|
||||
auto e = Actors.Get()[i];
|
||||
auto e = list.Get()[i];
|
||||
e.Bounds.Center -= origin;
|
||||
if (view.RenderLayersMask.Mask & e.LayerMask && (e.NoCulling || frustum.Intersects(e.Bounds)))
|
||||
{
|
||||
@@ -82,7 +83,7 @@ void SceneRendering::Draw(RenderContext& renderContext)
|
||||
}
|
||||
}
|
||||
#if USE_EDITOR
|
||||
if (view.Pass & DrawPass::GBuffer)
|
||||
if (view.Pass & DrawPass::GBuffer && category == SceneDraw)
|
||||
{
|
||||
// Draw physics shapes
|
||||
if (view.Flags & ViewFlags::PhysicsDebug || view.Mode == ViewMode::PhysicsColliders)
|
||||
@@ -116,42 +117,44 @@ void SceneRendering::Clear()
|
||||
listener->_scenes.Remove(this);
|
||||
}
|
||||
_listeners.Clear();
|
||||
Actors.Clear();
|
||||
for (auto& e : Actors)
|
||||
e.Clear();
|
||||
#if USE_EDITOR
|
||||
PhysicsDebug.Clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SceneRendering::AddActor(Actor* a, int32& key)
|
||||
void SceneRendering::AddActor(Actor* a, int32& key, DrawCategory category)
|
||||
{
|
||||
if (key != -1)
|
||||
return;
|
||||
ScopeLock lock(Locker);
|
||||
if (key == -1)
|
||||
auto& list = Actors[(int32)category];
|
||||
// TODO: track removedCount and skip searching for free entry if there is none
|
||||
key = 0;
|
||||
for (; key < list.Count(); key++)
|
||||
{
|
||||
// TODO: track removedCount and skip searching for free entry if there is none
|
||||
key = 0;
|
||||
for (; key < Actors.Count(); key++)
|
||||
{
|
||||
if (Actors[key].Actor == nullptr)
|
||||
break;
|
||||
}
|
||||
if (key == Actors.Count())
|
||||
Actors.AddOne();
|
||||
auto& e = Actors[key];
|
||||
e.Actor = a;
|
||||
e.LayerMask = a->GetLayerMask();
|
||||
e.Bounds = a->GetSphere();
|
||||
e.NoCulling = a->_drawNoCulling;
|
||||
for (auto* listener : _listeners)
|
||||
listener->OnSceneRenderingAddActor(a);
|
||||
if (list[key].Actor == nullptr)
|
||||
break;
|
||||
}
|
||||
if (key == list.Count())
|
||||
list.AddOne();
|
||||
auto& e = list[key];
|
||||
e.Actor = a;
|
||||
e.LayerMask = a->GetLayerMask();
|
||||
e.Bounds = a->GetSphere();
|
||||
e.NoCulling = a->_drawNoCulling;
|
||||
for (auto* listener : _listeners)
|
||||
listener->OnSceneRenderingAddActor(a);
|
||||
}
|
||||
|
||||
void SceneRendering::UpdateActor(Actor* a, int32 key)
|
||||
void SceneRendering::UpdateActor(Actor* a, int32 key, DrawCategory category)
|
||||
{
|
||||
ScopeLock lock(Locker);
|
||||
if (Actors.IsEmpty())
|
||||
auto& list = Actors[(int32)category];
|
||||
if (list.IsEmpty())
|
||||
return;
|
||||
auto& e = Actors[key];
|
||||
auto& e = list[key];
|
||||
ASSERT_LOW_LAYER(a == e.Actor);
|
||||
for (auto* listener : _listeners)
|
||||
listener->OnSceneRenderingUpdateActor(a, e.Bounds);
|
||||
@@ -159,12 +162,13 @@ void SceneRendering::UpdateActor(Actor* a, int32 key)
|
||||
e.Bounds = a->GetSphere();
|
||||
}
|
||||
|
||||
void SceneRendering::RemoveActor(Actor* a, int32& key)
|
||||
void SceneRendering::RemoveActor(Actor* a, int32& key, DrawCategory category)
|
||||
{
|
||||
ScopeLock lock(Locker);
|
||||
if (Actors.HasItems())
|
||||
auto& list = Actors[(int32)category];
|
||||
if (list.HasItems())
|
||||
{
|
||||
auto& e = Actors[key];
|
||||
auto& e = list[key];
|
||||
ASSERT_LOW_LAYER(a == e.Actor);
|
||||
for (auto* listener : _listeners)
|
||||
listener->OnSceneRenderingRemoveActor(a);
|
||||
|
||||
@@ -74,7 +74,18 @@ public:
|
||||
BoundingSphere Bounds;
|
||||
};
|
||||
|
||||
Array<DrawActor> Actors;
|
||||
/// <summary>
|
||||
/// Drawing categories for separate draw stages.
|
||||
/// </summary>
|
||||
enum DrawCategory
|
||||
{
|
||||
SceneDraw = 0,
|
||||
PreRender,
|
||||
PostRender,
|
||||
MAX
|
||||
};
|
||||
|
||||
Array<DrawActor> Actors[MAX];
|
||||
Array<IPostFxSettingsProvider*> PostFxProviders;
|
||||
CriticalSection Locker;
|
||||
|
||||
@@ -93,7 +104,8 @@ public:
|
||||
/// Draws the scene. Performs the optimized actors culling and draw calls submission for the current render pass (defined by the render view).
|
||||
/// </summary>
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
void Draw(RenderContext& renderContext);
|
||||
/// <param name="category">The actors category to draw.</param>
|
||||
void Draw(RenderContext& renderContext, DrawCategory category = DrawCategory::SceneDraw);
|
||||
|
||||
/// <summary>
|
||||
/// Collects the post fx volumes for the given rendering view.
|
||||
@@ -107,9 +119,9 @@ public:
|
||||
void Clear();
|
||||
|
||||
public:
|
||||
void AddActor(Actor* a, int32& key);
|
||||
void UpdateActor(Actor* a, int32 key);
|
||||
void RemoveActor(Actor* a, int32& key);
|
||||
void AddActor(Actor* a, int32& key, DrawCategory category = SceneDraw);
|
||||
void UpdateActor(Actor* a, int32 key, DrawCategory category = SceneDraw);
|
||||
void RemoveActor(Actor* a, int32& key, DrawCategory category = SceneDraw);
|
||||
|
||||
FORCE_INLINE void AddPostFxProvider(IPostFxSettingsProvider* obj)
|
||||
{
|
||||
|
||||
@@ -483,7 +483,8 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
_cullingPosDistance = Vector4(viewPosition, distance);
|
||||
for (auto* scene : renderContext.List->Scenes)
|
||||
{
|
||||
for (auto& e : scene->Actors)
|
||||
auto& list = scene->Actors[SceneRendering::SceneDraw];
|
||||
for (auto& e : list)
|
||||
{
|
||||
if (viewMask & e.LayerMask && e.Bounds.Radius >= minObjectRadius && CollisionsHelper::DistanceSpherePoint(e.Bounds, viewPosition) < distance)
|
||||
{
|
||||
|
||||
@@ -542,7 +542,8 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
|
||||
_cascadeCullingBounds = cascadeBoundsWorld;
|
||||
for (SceneRendering* scene : renderContext.List->Scenes)
|
||||
{
|
||||
for (const auto& e : scene->Actors)
|
||||
auto& list = scene->Actors[SceneRendering::SceneDraw];
|
||||
for (const auto& e : list)
|
||||
{
|
||||
if (viewMask & e.LayerMask && e.Bounds.Radius >= minObjectRadius && CollisionsHelper::BoxIntersectsSphere(cascadeBoundsWorld, e.Bounds))
|
||||
{
|
||||
|
||||
@@ -122,7 +122,8 @@ void RendererService::Dispose()
|
||||
void RenderAntiAliasingPass(RenderContext& renderContext, GPUTexture* input, GPUTextureView* output)
|
||||
{
|
||||
auto context = GPUDevice::Instance->GetMainContext();
|
||||
context->SetViewportAndScissors(renderContext.View.ScreenSize.X, renderContext.View.ScreenSize.Y);
|
||||
auto screenSize = renderContext.View.ScreenSize;
|
||||
context->SetViewportAndScissors(screenSize.X, screenSize.Y);
|
||||
|
||||
const auto aaMode = renderContext.List->Settings.AntiAliasing.Mode;
|
||||
if (aaMode == AntialiasingMode::FastApproximateAntialiasing)
|
||||
@@ -165,10 +166,8 @@ void Renderer::Render(SceneRenderTask* task)
|
||||
PROFILE_GPU_CPU_NAMED("Render Frame");
|
||||
|
||||
auto context = GPUDevice::Instance->GetMainContext();
|
||||
|
||||
context->ClearState();
|
||||
context->FlushState();
|
||||
|
||||
const Viewport viewport = task->GetViewport();
|
||||
context->SetViewportAndScissors(viewport);
|
||||
|
||||
|
||||
@@ -161,8 +161,8 @@ void ScreenSpaceReflectionsPass::Render(RenderContext& renderContext, GPUTexture
|
||||
// Skip pass if resources aren't ready
|
||||
if (checkIfSkipPass())
|
||||
return;
|
||||
auto& view = renderContext.View;
|
||||
auto buffers = renderContext.Buffers;
|
||||
const RenderView& view = renderContext.View;
|
||||
RenderBuffers* buffers = renderContext.Buffers;
|
||||
|
||||
// TODO: add support for SSR in ortho projection
|
||||
if (view.IsOrthographicProjection())
|
||||
@@ -275,7 +275,7 @@ void ScreenSpaceReflectionsPass::Render(RenderContext& renderContext, GPUTexture
|
||||
GlobalSignDistanceFieldPass::BindingData bindingDataSDF;
|
||||
GlobalSurfaceAtlasPass::BindingData bindingDataSurfaceAtlas;
|
||||
if (settings.TraceMode == ReflectionsTraceMode::SoftwareTracing &&
|
||||
renderContext.View.Flags & ViewFlags::GI &&
|
||||
view.Flags & ViewFlags::GI &&
|
||||
renderContext.List->Settings.GlobalIllumination.Mode == GlobalIlluminationMode::DDGI)
|
||||
{
|
||||
if (!GlobalSignDistanceFieldPass::Instance()->Render(renderContext, context, bindingDataSDF) &&
|
||||
|
||||
Reference in New Issue
Block a user