Refactor Actor::Draw to use only variant with RenderContextBatch to simplify rendering code
This commit is contained in:
@@ -89,6 +89,24 @@ public:
|
||||
Meshes.Get()[i].Draw(renderContext, material, world, flags, receiveDecals, drawModes, perInstanceRandom, sortOrder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the meshes from the model LOD.
|
||||
/// </summary>
|
||||
/// <param name="renderContextBatch">The rendering context batch.</param>
|
||||
/// <param name="material">The material to use for rendering.</param>
|
||||
/// <param name="world">The world transformation of the model.</param>
|
||||
/// <param name="flags">The object static flags.</param>
|
||||
/// <param name="receiveDecals">True if rendered geometry can receive decals, otherwise false.</param>
|
||||
/// <param name="drawModes">The draw passes to use for rendering this object.</param>
|
||||
/// <param name="perInstanceRandom">The random per-instance value (normalized to range 0-1).</param>
|
||||
/// <param name="sortOrder">Object sorting key.</param>
|
||||
/// <param name="shadowsMode">The object shadows casting mode.</param>
|
||||
void Draw(API_PARAM(Ref) const RenderContextBatch& renderContextBatch, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true, DrawPass drawModes = DrawPass::Default, float perInstanceRandom = 0.0f, int8 sortOrder = 0, ShadowsCastingMode shadowsMode = ShadowsCastingMode::All) const
|
||||
{
|
||||
for (int32 i = 0; i < Meshes.Count(); i++)
|
||||
Meshes.Get()[i].Draw(renderContextBatch, material, world, flags, receiveDecals, drawModes, perInstanceRandom, sortOrder, 0, shadowsMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws all the meshes from the model LOD.
|
||||
/// </summary>
|
||||
|
||||
@@ -1205,16 +1205,16 @@ bool Foliage::Intersects(const Ray& ray, Real& distance, Vector3& normal, int32&
|
||||
return false;
|
||||
}
|
||||
|
||||
void Foliage::Draw(RenderContext& renderContext)
|
||||
void Foliage::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
if (Instances.IsEmpty())
|
||||
return;
|
||||
PROFILE_CPU();
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
const RenderView& view = renderContext.View;
|
||||
PreDraw(view);
|
||||
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSDF)
|
||||
{
|
||||
// Draw into Global SDF
|
||||
auto globalSDF = GlobalSignDistanceFieldPass::Instance();
|
||||
BoundingBox globalSDFBounds;
|
||||
globalSDF->GetCullingData(globalSDFBounds);
|
||||
@@ -1240,7 +1240,6 @@ void Foliage::Draw(RenderContext& renderContext)
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas)
|
||||
{
|
||||
// Draw foliage instances into Global Surface Atlas
|
||||
@@ -1294,34 +1293,8 @@ void Foliage::Draw(RenderContext& renderContext)
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw visible clusters
|
||||
#if FOLIAGE_USE_SINGLE_QUAD_TREE || !FOLIAGE_USE_DRAW_CALLS_BATCHING
|
||||
Mesh::DrawInfo draw;
|
||||
draw.Flags = GetStaticFlags();
|
||||
draw.DrawModes = (DrawPass)(DrawPass::Default & view.Pass);
|
||||
#endif
|
||||
#if FOLIAGE_USE_SINGLE_QUAD_TREE
|
||||
if (Root)
|
||||
DrawCluster(renderContext, Root, draw);
|
||||
#else
|
||||
for (auto& type : FoliageTypes)
|
||||
{
|
||||
#if !FOLIAGE_USE_SINGLE_QUAD_TREE && FOLIAGE_USE_DRAW_CALLS_BATCHING
|
||||
DrawCallsList draw[MODEL_MAX_LODS];
|
||||
#endif
|
||||
DrawType(renderContext, type, draw);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Foliage::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
if (Instances.IsEmpty())
|
||||
return;
|
||||
|
||||
#if !FOLIAGE_USE_SINGLE_QUAD_TREE
|
||||
// Run async job for each foliage type
|
||||
const RenderView& view = renderContextBatch.GetMainContext().View;
|
||||
if (EnumHasAnyFlags(view.Pass, DrawPass::GBuffer) && !(view.Pass & (DrawPass::GlobalSDF | DrawPass::GlobalSurfaceAtlas)) && renderContextBatch.EnableAsync)
|
||||
{
|
||||
PreDraw(view);
|
||||
@@ -1336,8 +1309,28 @@ void Foliage::Draw(RenderContextBatch& renderContextBatch)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fallback to default rendering
|
||||
Actor::Draw(renderContextBatch);
|
||||
// Draw visible clusters
|
||||
#if FOLIAGE_USE_SINGLE_QUAD_TREE || !FOLIAGE_USE_DRAW_CALLS_BATCHING
|
||||
Mesh::DrawInfo draw;
|
||||
draw.Flags = GetStaticFlags();
|
||||
draw.DrawModes = (DrawPass)(DrawPass::Default & view.Pass);
|
||||
#endif
|
||||
#if FOLIAGE_USE_SINGLE_QUAD_TREE
|
||||
if (Root)
|
||||
{
|
||||
for (RenderContext& c : renderContextBatch.Contexts)
|
||||
DrawCluster(c, Root, draw);
|
||||
}
|
||||
#else
|
||||
for (auto& type : FoliageTypes)
|
||||
{
|
||||
#if !FOLIAGE_USE_SINGLE_QUAD_TREE && FOLIAGE_USE_DRAW_CALLS_BATCHING
|
||||
DrawCallsList draw[MODEL_MAX_LODS];
|
||||
#endif
|
||||
for (RenderContext& c : renderContextBatch.Contexts)
|
||||
DrawType(c, type, draw);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Foliage::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal)
|
||||
|
||||
@@ -239,7 +239,6 @@ private:
|
||||
|
||||
public:
|
||||
// [Actor]
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
|
||||
@@ -251,6 +251,42 @@ void Mesh::Draw(const RenderContext& renderContext, MaterialBase* material, cons
|
||||
renderContext.List->AddDrawCall(renderContext, drawModes, flags, drawCall, receiveDecals, sortOrder);
|
||||
}
|
||||
|
||||
void Mesh::Draw(const RenderContextBatch& renderContextBatch, MaterialBase* material, const Matrix& world, StaticFlags flags, bool receiveDecals, DrawPass drawModes, float perInstanceRandom, int8 sortOrder, uint8 stencilValue, ShadowsCastingMode shadowsMode) const
|
||||
{
|
||||
if (!material || !material->IsSurface() || !IsInitialized())
|
||||
return;
|
||||
drawModes &= material->GetDrawModes();
|
||||
if (drawModes == DrawPass::None)
|
||||
return;
|
||||
|
||||
// Setup draw call
|
||||
DrawCall drawCall;
|
||||
drawCall.Geometry.IndexBuffer = _indexBuffer;
|
||||
drawCall.Geometry.VertexBuffers[0] = _vertexBuffers[0];
|
||||
drawCall.Geometry.VertexBuffers[1] = _vertexBuffers[1];
|
||||
drawCall.Geometry.VertexBuffers[2] = _vertexBuffers[2];
|
||||
drawCall.Draw.IndicesCount = _triangles * 3;
|
||||
drawCall.InstanceCount = 1;
|
||||
drawCall.Material = material;
|
||||
drawCall.World = world;
|
||||
drawCall.ObjectPosition = drawCall.World.GetTranslation();
|
||||
drawCall.ObjectRadius = (float)_sphere.Radius * drawCall.World.GetScaleVector().GetAbsolute().MaxValue();
|
||||
drawCall.Surface.GeometrySize = _box.GetSize();
|
||||
drawCall.Surface.PrevWorld = world;
|
||||
drawCall.PerInstanceRandom = perInstanceRandom;
|
||||
drawCall.StencilValue = stencilValue;
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
#if GPU_ENABLE_DEVELOPMENT
|
||||
const ViewMode viewMode = renderContext.View.Mode;
|
||||
if (viewMode == ViewMode::LightmapUVsDensity || viewMode == ViewMode::LODPreview)
|
||||
GBufferPass::AddIndexBufferToModelLOD(_indexBuffer, &((Model*)_model)->LODs[_lodIndex]);
|
||||
#endif
|
||||
|
||||
// Push draw call to the render list
|
||||
BoundingSphere bounds(drawCall.ObjectPosition, drawCall.ObjectRadius);
|
||||
renderContext.List->AddDrawCall(renderContextBatch, drawModes, flags, shadowsMode, bounds, drawCall, receiveDecals, sortOrder);
|
||||
}
|
||||
|
||||
void Mesh::Draw(const RenderContext& renderContext, const DrawInfo& info, float lodDitherFactor) const
|
||||
{
|
||||
const auto& entry = info.Buffer->At(_materialSlotIndex);
|
||||
|
||||
@@ -142,6 +142,21 @@ public:
|
||||
/// <param name="stencilValue">Object stencil value.</param>
|
||||
API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true, DrawPass drawModes = DrawPass::Default, float perInstanceRandom = 0.0f, int8 sortOrder = 0, uint8 stencilValue = 0) const;
|
||||
|
||||
/// <summary>
|
||||
/// Draws the mesh.
|
||||
/// </summary>
|
||||
/// <param name="renderContextBatch">The rendering context batch.</param>
|
||||
/// <param name="material">The material to use for rendering.</param>
|
||||
/// <param name="world">The world transformation of the model.</param>
|
||||
/// <param name="flags">The object static flags.</param>
|
||||
/// <param name="receiveDecals">True if rendered geometry can receive decals, otherwise false.</param>
|
||||
/// <param name="drawModes">The draw passes to use for rendering this object.</param>
|
||||
/// <param name="perInstanceRandom">The random per-instance value (normalized to range 0-1).</param>
|
||||
/// <param name="sortOrder">Object sorting key.</param>
|
||||
/// <param name="stencilValue">Object stencil value.</param>
|
||||
/// <param name="shadowsMode">The object shadows casting mode.</param>
|
||||
void Draw(API_PARAM(Ref) const RenderContextBatch& renderContextBatch, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true, DrawPass drawModes = DrawPass::Default, float perInstanceRandom = 0.0f, int8 sortOrder = 0, uint8 stencilValue = 0, ShadowsCastingMode shadowsMode = ShadowsCastingMode::All) const;
|
||||
|
||||
/// <summary>
|
||||
/// Draws the mesh.
|
||||
/// </summary>
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "Engine/Core/Collections/CollectionPoolCache.h"
|
||||
#include "Engine/Core/Math/Double4x4.h"
|
||||
#include "Engine/Debug/Exceptions/JsonParseException.h"
|
||||
#include "Engine/Graphics/RenderContext.h"
|
||||
#include "Engine/Physics/Physics.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Profiler/ProfilerMemory.h"
|
||||
@@ -1485,15 +1484,8 @@ void Actor::InitializeHierarchy()
|
||||
Children[i]->InitializeHierarchy();
|
||||
}
|
||||
|
||||
void Actor::Draw(RenderContext& renderContext)
|
||||
{
|
||||
}
|
||||
|
||||
void Actor::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
// Default impl calls single-context
|
||||
for (RenderContext& renderContext : renderContextBatch.Contexts)
|
||||
Draw(renderContext);
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
@@ -738,13 +738,7 @@ public:
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Draws this actor. Called by Scene Rendering service. This call is more optimized than generic Draw (eg. geometry is rendered during all pass types but other actors are drawn only during GBufferFill pass).
|
||||
/// </summary>
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
virtual void Draw(RenderContext& renderContext);
|
||||
|
||||
/// <summary>
|
||||
/// Draws this actor. Called by Scene Rendering service. This call is more optimized than generic Draw (eg. geometry is rendered during all pass types but other actors are drawn only during GBufferFill pass).
|
||||
/// Draws this actor. Called by Scene Rendering to collect draw calls from objects.
|
||||
/// </summary>
|
||||
/// <param name="renderContextBatch">The rendering context batch (eg, main view and shadow projections).</param>
|
||||
virtual void Draw(RenderContextBatch& renderContextBatch);
|
||||
|
||||
@@ -1250,64 +1250,14 @@ void AnimatedModel::Update()
|
||||
_lastMinDstSqr = MAX_Real;
|
||||
}
|
||||
|
||||
void AnimatedModel::Draw(RenderContext& renderContext)
|
||||
{
|
||||
if (!SkinnedModel || !SkinnedModel->IsLoaded())
|
||||
return;
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSDF)
|
||||
return;
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas)
|
||||
return; // Not supported
|
||||
auto drawState = renderContext.Buffers->GetGeometryDrawState(&GetScene()->Rendering, _sceneRenderingKey, this);
|
||||
ACTOR_GET_WORLD_MATRIX(this, view, world);
|
||||
GEOMETRY_DRAW_STATE_EVENT_BEGIN(drawState, world);
|
||||
|
||||
_lastMinDstSqr = Math::Min(_lastMinDstSqr, Vector3::DistanceSquared(_transform.Translation, renderContext.View.WorldPosition));
|
||||
if (_bones.IsAllocated)
|
||||
{
|
||||
// Flush skinning data with GPU
|
||||
if (_bones.IsDirty)
|
||||
_bones.Flush();
|
||||
|
||||
SkinnedMesh::DrawInfo draw;
|
||||
draw.Buffer = &Entries;
|
||||
draw.SkinningBones = RenderListExtension.GlobalBuffer;
|
||||
draw.SkinningBonesOffset = _bones.GlobalBufferOffset / sizeof(Matrix3x4);
|
||||
draw.WithPrevBones = _bones.HasPrevBones && _bones.IsPrevFlushed;
|
||||
if (draw.WithPrevBones)
|
||||
{
|
||||
draw.PrevBonesOffset = _bones.BonesCount;
|
||||
if (_bones.IsPrevBones)
|
||||
{
|
||||
draw.SkinningBonesOffset += draw.PrevBonesOffset;
|
||||
draw.PrevBonesOffset = -draw.PrevBonesOffset;
|
||||
}
|
||||
}
|
||||
draw.World = &world;
|
||||
draw.DrawState = drawState;
|
||||
draw.Deformation = _deformation;
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
draw.DrawModes = DrawModes & renderContext.View.GetShadowsDrawPassMask(ShadowsMode);
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
draw.Bounds = _sphere;
|
||||
draw.Bounds.Center -= renderContext.View.Origin;
|
||||
draw.PerInstanceRandom = GetPerInstanceRandom();
|
||||
draw.LODBias = LODBias;
|
||||
draw.ForcedLOD = ForcedLOD;
|
||||
draw.SortOrder = SortOrder;
|
||||
draw.SetStencilValue(_layer);
|
||||
|
||||
SkinnedModel->Draw(renderContext, draw);
|
||||
}
|
||||
|
||||
GEOMETRY_DRAW_STATE_EVENT_END(drawState, world);
|
||||
}
|
||||
|
||||
void AnimatedModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
if (!SkinnedModel || !SkinnedModel->IsLoaded())
|
||||
auto model = SkinnedModel.Get();
|
||||
if (!model || !model->IsLoaded())
|
||||
return;
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSDF || renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas)
|
||||
return; // Not supported
|
||||
Matrix world;
|
||||
const Float3 translation = _transform.Translation - renderContext.View.Origin;
|
||||
Matrix::Transformation(_transform.Scale, _transform.Orientation, translation, world);
|
||||
@@ -1331,6 +1281,7 @@ void AnimatedModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
draw.PrevBonesOffset = _bones.BonesCount;
|
||||
if (_bones.IsPrevBones)
|
||||
{
|
||||
// Swap bone buffer chunks
|
||||
draw.SkinningBonesOffset += draw.PrevBonesOffset;
|
||||
draw.PrevBonesOffset = -draw.PrevBonesOffset;
|
||||
}
|
||||
@@ -1347,7 +1298,7 @@ void AnimatedModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
draw.SortOrder = SortOrder;
|
||||
draw.SetStencilValue(_layer);
|
||||
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
if (ShadowsMode != ShadowsCastingMode::All)
|
||||
{
|
||||
// To handle old ShadowsMode option for all meshes we need to call per-context drawing (no batching opportunity)
|
||||
@@ -1355,14 +1306,14 @@ void AnimatedModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
for (auto& e : renderContextBatch.Contexts)
|
||||
{
|
||||
draw.DrawModes = DrawModes & e.View.GetShadowsDrawPassMask(ShadowsMode);
|
||||
SkinnedModel->Draw(e, draw);
|
||||
model->Draw(e, draw);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SkinnedModel->Draw(renderContextBatch, draw);
|
||||
model->Draw(renderContextBatch, draw);
|
||||
}
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
}
|
||||
|
||||
GEOMETRY_DRAW_STATE_EVENT_END(drawState, world);
|
||||
|
||||
@@ -494,7 +494,6 @@ private:
|
||||
public:
|
||||
// [ModelInstanceActor]
|
||||
bool HasContentLoaded() const override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
#if USE_EDITOR
|
||||
void OnDebugDrawSelected() override;
|
||||
|
||||
@@ -355,8 +355,9 @@ bool Camera::HasContentLoaded() const
|
||||
return _previewModel == nullptr || _previewModel->IsLoaded();
|
||||
}
|
||||
|
||||
void Camera::Draw(RenderContext& renderContext)
|
||||
void Camera::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
if (EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::EditorSprites)
|
||||
&& renderContext.View.CullingFrustum.Intersects(_previewModelBox)
|
||||
&& _previewModel
|
||||
|
||||
@@ -266,7 +266,7 @@ public:
|
||||
#if USE_EDITOR
|
||||
BoundingBox GetEditorBox() const override;
|
||||
bool HasContentLoaded() const override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
void OnDebugDrawSelected() override;
|
||||
#endif
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
|
||||
@@ -67,8 +67,9 @@ void Decal::OnLayerChanged()
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, ISceneRenderingListener::Layer);
|
||||
}
|
||||
|
||||
void Decal::Draw(RenderContext& renderContext)
|
||||
void Decal::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
MaterialBase* material = Material;
|
||||
if (EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::Decals) &&
|
||||
EnumHasAnyFlags(renderContext.View.Pass, DrawPass::GBuffer) &&
|
||||
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
BoundingBox GetEditorBox() const override;
|
||||
#endif
|
||||
void OnLayerChanged() override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
||||
|
||||
@@ -17,8 +17,9 @@ DirectionalLight::DirectionalLight(const SpawnParams& params)
|
||||
Brightness = 8.0f;
|
||||
}
|
||||
|
||||
void DirectionalLight::Draw(RenderContext& renderContext)
|
||||
void DirectionalLight::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
float brightness = Brightness;
|
||||
AdjustBrightness(renderContext.View, brightness);
|
||||
Float3 color = Color.ToFloat3() * (Color.A * brightness);
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
|
||||
public:
|
||||
// [LightWithShadow]
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
||||
|
||||
@@ -181,8 +181,9 @@ void EnvironmentProbe::UpdateBounds()
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, ISceneRenderingListener::Bounds);
|
||||
}
|
||||
|
||||
void EnvironmentProbe::Draw(RenderContext& renderContext)
|
||||
void EnvironmentProbe::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
if (Brightness > ZeroTolerance &&
|
||||
EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::Reflections) &&
|
||||
EnumHasAnyFlags(renderContext.View.Pass, DrawPass::GBuffer))
|
||||
|
||||
@@ -158,7 +158,7 @@ public:
|
||||
return BoundingBox(_transform.Translation - size, _transform.Translation + size);
|
||||
}
|
||||
#endif
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
#if USE_EDITOR
|
||||
void OnDebugDrawSelected() override;
|
||||
#endif
|
||||
|
||||
@@ -31,10 +31,9 @@ ExponentialHeightFog::ExponentialHeightFog(const SpawnParams& params)
|
||||
#endif
|
||||
}
|
||||
|
||||
void ExponentialHeightFog::Draw(RenderContext& renderContext)
|
||||
void ExponentialHeightFog::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
// Render only when shader is valid and fog can be rendered
|
||||
// Do not render exponential fog in orthographic views
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
if (EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::Fog)
|
||||
&& EnumHasAnyFlags(renderContext.View.Pass, DrawPass::GBuffer)
|
||||
&& _shader
|
||||
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
return BoundingBox(_transform.Translation - size, _transform.Translation + size);
|
||||
}
|
||||
#endif
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
bool HasContentLoaded() const override;
|
||||
|
||||
@@ -81,8 +81,9 @@ void PointLight::OnTransformChanged()
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void PointLight::Draw(RenderContext& renderContext)
|
||||
void PointLight::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
float brightness = ComputeBrightness();
|
||||
AdjustBrightness(renderContext.View, brightness);
|
||||
Float3 position;
|
||||
|
||||
@@ -91,7 +91,7 @@ private:
|
||||
|
||||
public:
|
||||
// [LightWithShadow]
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
#if USE_EDITOR
|
||||
void OnDebugDraw() override;
|
||||
void OnDebugDrawSelected() override;
|
||||
|
||||
@@ -83,8 +83,9 @@ void Sky::InitConfig(ShaderAtmosphericFogData& config) const
|
||||
}
|
||||
}
|
||||
|
||||
void Sky::Draw(RenderContext& renderContext)
|
||||
void Sky::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
if (HasContentLoaded() && EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::Sky))
|
||||
{
|
||||
// Ensure to have pipeline state cache created
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
return BoundingBox(_transform.Translation - size, _transform.Translation + size);
|
||||
}
|
||||
#endif
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
bool HasContentLoaded() const override;
|
||||
|
||||
@@ -108,8 +108,9 @@ void SkyLight::UpdateBounds()
|
||||
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey, ISceneRenderingListener::Bounds);
|
||||
}
|
||||
|
||||
void SkyLight::Draw(RenderContext& renderContext)
|
||||
void SkyLight::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
float brightness = Brightness;
|
||||
AdjustBrightness(renderContext.View, brightness);
|
||||
const Float3 position = GetPosition() - renderContext.View.Origin;
|
||||
|
||||
@@ -107,7 +107,7 @@ private:
|
||||
|
||||
public:
|
||||
// [Light]
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
#if USE_EDITOR
|
||||
void OnDebugDrawSelected() override;
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@ void Skybox::setupProxy()
|
||||
}
|
||||
}
|
||||
|
||||
void Skybox::Draw(RenderContext& renderContext)
|
||||
void Skybox::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
bool isReady;
|
||||
if (CustomMaterial)
|
||||
@@ -41,6 +41,7 @@ void Skybox::Draw(RenderContext& renderContext)
|
||||
setupProxy();
|
||||
isReady = _proxyMaterial && _proxyMaterial->IsReady();
|
||||
}
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
if (isReady && EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::Sky))
|
||||
{
|
||||
renderContext.List->Sky = this;
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
return BoundingBox(_transform.Translation - size, _transform.Translation + size);
|
||||
}
|
||||
#endif
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
bool HasContentLoaded() const override;
|
||||
|
||||
@@ -382,12 +382,12 @@ bool SplineModel::HasContentLoaded() const
|
||||
return (Model == nullptr || Model->IsLoaded()) && Entries.HasContentLoaded();
|
||||
}
|
||||
|
||||
void SplineModel::Draw(RenderContext& renderContext)
|
||||
void SplineModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
const DrawPass actorDrawModes = DrawModes & renderContext.View.Pass;
|
||||
if (!_spline || !Model || !Model->IsLoaded() || !Model->CanBeRendered() || actorDrawModes == DrawPass::None)
|
||||
return;
|
||||
auto model = Model.Get();
|
||||
if (!_spline || !model || !model->IsLoaded() || !model->CanBeRendered())
|
||||
return;
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSDF)
|
||||
return; // TODO: Spline Model rendering to Global SDF
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas)
|
||||
@@ -466,14 +466,14 @@ void SplineModel::Draw(RenderContext& renderContext)
|
||||
|
||||
// Check if skip rendering
|
||||
const auto shadowsMode = entry.ShadowsMode & slot.ShadowsMode;
|
||||
const auto drawModes = actorDrawModes & renderContext.View.GetShadowsDrawPassMask(shadowsMode) & material->GetDrawModes();
|
||||
const auto drawModes = DrawModes & material->GetDrawModes();
|
||||
if (drawModes == DrawPass::None)
|
||||
continue;
|
||||
|
||||
// Submit draw call
|
||||
mesh->GetDrawCallGeometry(drawCall);
|
||||
drawCall.Material = material;
|
||||
renderContext.List->AddDrawCall(renderContext, drawModes, _staticFlags, drawCall, entry.ReceiveDecals);
|
||||
renderContext.List->AddDrawCall(renderContextBatch, drawModes, _staticFlags, shadowsMode, instanceSphere, drawCall, entry.ReceiveDecals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ private:
|
||||
public:
|
||||
// [ModelInstanceActor]
|
||||
bool HasContentLoaded() const override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
|
||||
@@ -128,8 +128,9 @@ void SpotLight::OnTransformChanged()
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void SpotLight::Draw(RenderContext& renderContext)
|
||||
void SpotLight::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
float brightness = ComputeBrightness();
|
||||
AdjustBrightness(renderContext.View, brightness);
|
||||
Float3 position;
|
||||
|
||||
@@ -117,7 +117,7 @@ private:
|
||||
|
||||
public:
|
||||
// [LightWithShadow]
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
#if USE_EDITOR
|
||||
void OnDebugDraw() override;
|
||||
void OnDebugDrawSelected() override;
|
||||
|
||||
@@ -366,20 +366,22 @@ bool StaticModel::HasContentLoaded() const
|
||||
return (Model == nullptr || Model->IsLoaded()) && Entries.HasContentLoaded();
|
||||
}
|
||||
|
||||
void StaticModel::Draw(RenderContext& renderContext)
|
||||
void StaticModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
if (!Model || !Model->IsLoaded() || !Model->CanBeRendered())
|
||||
auto model = Model.Get();
|
||||
if (!model || !model->IsLoaded())
|
||||
return;
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSDF)
|
||||
{
|
||||
if (EnumHasAnyFlags(_drawModes, DrawPass::GlobalSDF) && Model->SDF.Texture)
|
||||
GlobalSignDistanceFieldPass::Instance()->RasterizeModelSDF(this, Model->SDF, _transform, _box);
|
||||
if (EnumHasAnyFlags(_drawModes, DrawPass::GlobalSDF) && model->SDF.Texture)
|
||||
GlobalSignDistanceFieldPass::Instance()->RasterizeModelSDF(this, model->SDF, _transform, _box);
|
||||
return;
|
||||
}
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas)
|
||||
{
|
||||
if (EnumHasAnyFlags(_drawModes, DrawPass::GlobalSurfaceAtlas) && Model->SDF.Texture)
|
||||
GlobalSurfaceAtlasPass::Instance()->RasterizeActor(this, this, _sphere, _transform, Model->LODs.Last().GetBox());
|
||||
if (EnumHasAnyFlags(_drawModes, DrawPass::GlobalSurfaceAtlas) && model->SDF.Texture)
|
||||
GlobalSurfaceAtlasPass::Instance()->RasterizeActor(this, this, _sphere, _transform, model->LODs.Last().GetBox());
|
||||
return;
|
||||
}
|
||||
auto drawState = renderContext.Buffers->GetGeometryDrawState(&GetScene()->Rendering, _sceneRenderingKey, this);
|
||||
@@ -410,45 +412,7 @@ void StaticModel::Draw(RenderContext& renderContext)
|
||||
draw.LightmapScale = _scaleInLightmap;
|
||||
#endif
|
||||
|
||||
Model->Draw(renderContext, draw);
|
||||
|
||||
GEOMETRY_DRAW_STATE_EVENT_END(drawState, world);
|
||||
}
|
||||
|
||||
void StaticModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
if (!Model || !Model->IsLoaded())
|
||||
return;
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
auto drawState = renderContext.Buffers->GetGeometryDrawState(&GetScene()->Rendering, _sceneRenderingKey, this);
|
||||
ACTOR_GET_WORLD_MATRIX(this, view, world);
|
||||
GEOMETRY_DRAW_STATE_EVENT_BEGIN(drawState, world);
|
||||
if (_vertexColorsDirty)
|
||||
FlushVertexColors();
|
||||
|
||||
Mesh::DrawInfo draw;
|
||||
draw.Buffer = &Entries;
|
||||
draw.World = &world;
|
||||
draw.DrawState = drawState;
|
||||
draw.Deformation = _deformation;
|
||||
draw.Lightmap = _scene && Lightmap.TextureIndex != -1 ? _scene->LightmapsData.GetReadyLightmap(Lightmap.TextureIndex) : nullptr;
|
||||
draw.LightmapUVs = &Lightmap.UVsArea;
|
||||
draw.Flags = _staticFlags;
|
||||
draw.DrawModes = _drawModes;
|
||||
draw.Bounds = _sphere;
|
||||
draw.Bounds.Center -= renderContext.View.Origin;
|
||||
draw.PerInstanceRandom = GetPerInstanceRandom();
|
||||
draw.LODBias = _lodBias;
|
||||
draw.ForcedLOD = _forcedLod;
|
||||
draw.SortOrder = _sortOrder;
|
||||
draw.VertexColors = _vertexColorsCount ? _vertexColorsBuffer : nullptr;
|
||||
draw.SetStencilValue(_layer);
|
||||
#if GPU_ENABLE_DEVELOPMENT
|
||||
if (HasStaticFlag(StaticFlags::Lightmap))
|
||||
draw.LightmapScale = _scaleInLightmap;
|
||||
#endif
|
||||
|
||||
Model->Draw(renderContextBatch, draw);
|
||||
model->Draw(renderContextBatch, draw);
|
||||
|
||||
GEOMETRY_DRAW_STATE_EVENT_END(drawState, world);
|
||||
}
|
||||
|
||||
@@ -169,7 +169,6 @@ private:
|
||||
public:
|
||||
// [ModelInstanceActor]
|
||||
bool HasContentLoaded() const override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
|
||||
@@ -276,7 +276,7 @@ void SceneRendering::DrawActorsJob(int32 i)
|
||||
FOR_EACH_BATCH_ACTOR
|
||||
if (CHECK_ACTOR_SINGLE_FRUSTUM)
|
||||
{
|
||||
DRAW_ACTOR(mainContext);
|
||||
DRAW_ACTOR(*_drawBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,21 +605,13 @@ bool ParticleEffect::HasContentLoaded() const
|
||||
return true;
|
||||
}
|
||||
|
||||
void ParticleEffect::Draw(RenderContext& renderContext)
|
||||
{
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSDF ||
|
||||
renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas ||
|
||||
EnumHasNoneFlags(renderContext.View.Flags, ViewFlags::Particles))
|
||||
return;
|
||||
_lastMinDstSqr = Math::Min(_lastMinDstSqr, Vector3::DistanceSquared(GetPosition(), renderContext.View.WorldPosition));
|
||||
RenderContextBatch renderContextBatch(renderContext);
|
||||
Particles::DrawParticles(renderContextBatch, this);
|
||||
}
|
||||
|
||||
void ParticleEffect::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
const RenderView& mainView = renderContextBatch.GetMainContext().View;
|
||||
if (EnumHasNoneFlags(mainView.Flags, ViewFlags::Particles))
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
const RenderView& mainView = renderContext.View;
|
||||
if (mainView.Pass == DrawPass::GlobalSDF ||
|
||||
mainView.Pass == DrawPass::GlobalSurfaceAtlas ||
|
||||
EnumHasNoneFlags(mainView.Flags, ViewFlags::Particles))
|
||||
return;
|
||||
Particles::DrawParticles(renderContextBatch, this);
|
||||
|
||||
|
||||
@@ -414,7 +414,6 @@ private:
|
||||
public:
|
||||
// [Actor]
|
||||
bool HasContentLoaded() const override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
#if USE_EDITOR
|
||||
void OnDebugDrawSelected() override;
|
||||
|
||||
@@ -908,12 +908,6 @@ void Cloth::OnPostUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
void Cloth::Draw(RenderContext& renderContext)
|
||||
{
|
||||
// Update min draw distance for the next simulation tick
|
||||
_lastMinDstSqr = Math::Min(_lastMinDstSqr, Vector3::DistanceSquared(_transform.Translation, renderContext.View.WorldPosition));
|
||||
}
|
||||
|
||||
void Cloth::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
// Update min draw distance for the next simulation tick
|
||||
|
||||
@@ -347,7 +347,6 @@ private:
|
||||
|
||||
public:
|
||||
// [Actor]
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/GPUPass.h"
|
||||
#include "Engine/Graphics/Graphics.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/RenderContext.h"
|
||||
#include "Engine/Graphics/RenderBuffers.h"
|
||||
#include "Engine/Graphics/RenderTargetPool.h"
|
||||
@@ -219,7 +218,7 @@ public:
|
||||
Array<void*> FailedObjects;
|
||||
Array<void*> PrevFrameFailedObjects;
|
||||
Array<int64> AsyncScenesDrawCounters[2];
|
||||
RenderContext AsyncRenderContext;
|
||||
RenderContextBatch AsyncRenderContextBatch;
|
||||
|
||||
GlobalSurfaceAtlasCustomBuffer()
|
||||
: ObjectsBuffer(256 * (GLOBAL_SURFACE_ATLAS_OBJECT_DATA_STRIDE + GLOBAL_SURFACE_ATLAS_TILE_DATA_STRIDE * 3 / 4), PixelFormat::R32G32B32A32_Float, false, TEXT("GlobalSurfaceAtlas.ObjectsBuffer"))
|
||||
@@ -280,9 +279,10 @@ public:
|
||||
auto drawCategory = index >= 0 ? SceneRendering::SceneDrawAsync : SceneRendering::SceneDraw;
|
||||
const Vector3 cullingPos(CullingPosDistance);
|
||||
const Real cullingDistance = CullingPosDistance.W;
|
||||
const uint32 viewMask = AsyncRenderContext.View.RenderLayersMask;
|
||||
const RenderContext& renderContext = AsyncRenderContextBatch.GetMainContext();
|
||||
const uint32 viewMask = renderContext.View.RenderLayersMask;
|
||||
const float minObjectRadius = MinObjectRadius;
|
||||
auto& scenes = AsyncRenderContext.List->Scenes;
|
||||
auto& scenes = renderContext.List->Scenes;
|
||||
auto& drawCounters = AsyncScenesDrawCounters[index >= 0 ? 1 : 0];
|
||||
|
||||
// Draw all scenes and all actors (cooperative with other jobs)
|
||||
@@ -297,7 +297,7 @@ public:
|
||||
if (e.Bounds.Radius >= minObjectRadius && viewMask & e.LayerMask && Vector3::Distance(e.Bounds.Center, cullingPos) - e.Bounds.Radius < cullingDistance)
|
||||
{
|
||||
//PROFILE_CPU_ACTOR(e.Actor);
|
||||
e.Actor->Draw(AsyncRenderContext);
|
||||
e.Actor->Draw(AsyncRenderContextBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,8 +373,8 @@ public:
|
||||
// TODO: add DetailsScale param to adjust quality of scene details in Global Surface Atlas
|
||||
MinObjectRadius = METERS_TO_UNITS(0.2f); // Skip too small objects
|
||||
CullingPosDistance = Vector4(renderContext.View.Position, distance);
|
||||
AsyncRenderContext = renderContext;
|
||||
AsyncRenderContext.View.Pass = DrawPass::GlobalSurfaceAtlas;
|
||||
AsyncRenderContextBatch = RenderContext(renderContext);
|
||||
AsyncRenderContextBatch.GetMainContext().View.Pass = DrawPass::GlobalSurfaceAtlas;
|
||||
|
||||
// Each scene uses own atomic counter to draw all actors
|
||||
AsyncScenesDrawCounters[0].Resize(renderContext.List->Scenes.Count());
|
||||
@@ -1135,7 +1135,8 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
PROFILE_GPU_CPU_NAMED("Rasterize Tiles");
|
||||
|
||||
// Init rendering context
|
||||
RenderContext renderContextTiles = renderContext;
|
||||
RenderContextBatch renderContextBatchTiles(renderContext);
|
||||
RenderContext& renderContextTiles = renderContextBatchTiles.GetMainContext();
|
||||
renderContextTiles.List = RenderList::GetFromPool();
|
||||
renderContextTiles.View.Pass = DrawPass::GBuffer | DrawPass::GlobalSurfaceAtlas;
|
||||
renderContextTiles.View.Mode = ViewMode::Default;
|
||||
@@ -1218,7 +1219,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
|
||||
// Collect draw calls for the object
|
||||
_currentActorObject = actorObject;
|
||||
object.Actor->Draw(renderContextTiles);
|
||||
object.Actor->Draw(renderContextBatchTiles);
|
||||
|
||||
// Render all tiles into the atlas
|
||||
#if GLOBAL_SURFACE_ATLAS_DEBUG_DRAW_OBJECTS
|
||||
|
||||
@@ -251,7 +251,7 @@ public:
|
||||
|
||||
// Async objects drawing cache
|
||||
Array<int64, FixedAllocation<1>> AsyncDrawWaitLabels;
|
||||
RenderContext AsyncRenderContext;
|
||||
RenderContextBatch AsyncRenderContextBatch;
|
||||
|
||||
~GlobalSignDistanceFieldCustomBuffer()
|
||||
{
|
||||
@@ -351,8 +351,8 @@ public:
|
||||
// Setup data for rendering
|
||||
if (FrameIndex++ > 128)
|
||||
FrameIndex = 0;
|
||||
AsyncRenderContext = renderContext;
|
||||
AsyncRenderContext.View.Pass = DrawPass::GlobalSDF;
|
||||
AsyncRenderContextBatch = RenderContextBatch(renderContext);
|
||||
AsyncRenderContextBatch.GetMainContext().View.Pass = DrawPass::GlobalSDF;
|
||||
DebugOverdraw = renderContext.View.Mode == ViewMode::GlobalSDFOverdraw;
|
||||
const bool useCache = !reset && !GLOBAL_SDF_DEBUG_FORCE_REDRAW;
|
||||
static_assert(GLOBAL_SDF_RASTERIZE_CHUNK_SIZE % GLOBAL_SDF_RASTERIZE_GROUP_SIZE == 0, "Invalid chunk size for Global SDF rasterization group size.");
|
||||
@@ -511,12 +511,13 @@ void GlobalSignDistanceFieldCustomBuffer::DrawCascadeActors(const CascadeData& c
|
||||
{
|
||||
PROFILE_CPU();
|
||||
const BoundingBox cullingBounds = cascade.CullingBounds;
|
||||
const uint32 viewMask = AsyncRenderContext.View.RenderLayersMask;
|
||||
auto& renderContext = AsyncRenderContextBatch.GetMainContext();
|
||||
const uint32 viewMask = renderContext.View.RenderLayersMask;
|
||||
// TODO: add scene detail scale factor to PostFx settings (eg. to increase or decrease scene details and quality)
|
||||
const float minObjectRadius = Math::Max(20.0f, cascade.VoxelSize * 2.0f); // Skip too small objects for this cascade
|
||||
int32 actorsDrawn = 0;
|
||||
SceneRendering::DrawCategory drawCategories[] = { SceneRendering::SceneDraw, SceneRendering::SceneDrawAsync };
|
||||
for (auto* scene : AsyncRenderContext.List->Scenes)
|
||||
for (auto* scene : renderContext.List->Scenes)
|
||||
{
|
||||
for (SceneRendering::DrawCategory drawCategory : drawCategories)
|
||||
{
|
||||
@@ -526,7 +527,7 @@ void GlobalSignDistanceFieldCustomBuffer::DrawCascadeActors(const CascadeData& c
|
||||
if (e.Bounds.Radius >= minObjectRadius && viewMask & e.LayerMask && CollisionsHelper::BoxIntersectsSphere(cullingBounds, e.Bounds))
|
||||
{
|
||||
//PROFILE_CPU_ACTOR(e.Actor);
|
||||
e.Actor->Draw(AsyncRenderContext);
|
||||
e.Actor->Draw(AsyncRenderContextBatch);
|
||||
#if COMPILE_WITH_PROFILER
|
||||
actorsDrawn++;
|
||||
#endif
|
||||
|
||||
@@ -749,7 +749,7 @@ void RenderList::AddDrawCall(const RenderContextBatch& renderContextBatch, DrawP
|
||||
// Add draw call to proper draw lists
|
||||
DrawPass modes = drawModes & mainRenderContext.View.GetShadowsDrawPassMask(shadowsMode);
|
||||
drawModes = modes & mainRenderContext.View.Pass;
|
||||
if (drawModes != DrawPass::None && mainRenderContext.View.CullingFrustum.Intersects(bounds))
|
||||
if (drawModes != DrawPass::None && (mainRenderContext.View.IsCullingDisabled || mainRenderContext.View.CullingFrustum.Intersects(bounds)))
|
||||
{
|
||||
if ((drawModes & DrawPass::Depth) != DrawPass::None)
|
||||
{
|
||||
|
||||
@@ -341,6 +341,12 @@ void Renderer::DrawPostFxMaterial(GPUContext* context, const RenderContext& rend
|
||||
}
|
||||
|
||||
void Renderer::DrawActors(RenderContext& renderContext, const Array<Actor*>& customActors)
|
||||
{
|
||||
RenderContextBatch renderContextBatch(renderContext);
|
||||
DrawActors(renderContextBatch, customActors);
|
||||
}
|
||||
|
||||
void Renderer::DrawActors(RenderContextBatch& renderContextBatch, const Array<Actor*>& customActors)
|
||||
{
|
||||
if (customActors.HasItems())
|
||||
{
|
||||
@@ -348,13 +354,12 @@ void Renderer::DrawActors(RenderContext& renderContext, const Array<Actor*>& cus
|
||||
for (Actor* actor : customActors)
|
||||
{
|
||||
if (actor && actor->GetIsActive())
|
||||
actor->Draw(renderContext);
|
||||
actor->Draw(renderContextBatch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw scene actors
|
||||
RenderContextBatch renderContextBatch(renderContext);
|
||||
JobSystem::SetJobStartingOnDispatch(false);
|
||||
Level::DrawActors(renderContextBatch, SceneRendering::DrawCategory::SceneDraw);
|
||||
Level::DrawActors(renderContextBatch, SceneRendering::DrawCategory::SceneDrawAsync);
|
||||
|
||||
@@ -8,6 +8,7 @@ class GPUContext;
|
||||
class GPUTexture;
|
||||
class GPUTextureView;
|
||||
struct RenderContext;
|
||||
struct RenderContextBatch;
|
||||
class RenderTask;
|
||||
class SceneRenderTask;
|
||||
class MaterialBase;
|
||||
@@ -56,4 +57,11 @@ public:
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
/// <param name="customActors">The custom set of actors to render. If empty, the loaded scenes will be rendered.</param>
|
||||
API_FUNCTION() static void DrawActors(API_PARAM(Ref) RenderContext& renderContext, API_PARAM(DefaultValue=null) const Array<Actor*, HeapAllocation>& customActors);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked drawing of the scene objects (collects draw calls into RenderList for all contexts in a batch).
|
||||
/// </summary>
|
||||
/// <param name="renderContextBatch">The rendering context batch.</param>
|
||||
/// <param name="customActors">The custom set of actors to render. If empty, the loaded scenes will be rendered.</param>
|
||||
API_FUNCTION() static void DrawActors(API_PARAM(Ref) RenderContextBatch& renderContextBatch, API_PARAM(DefaultValue=null) const Array<Actor*, HeapAllocation>& customActors);
|
||||
};
|
||||
|
||||
@@ -541,18 +541,6 @@ void Terrain::Draw(RenderContextBatch& renderContextBatch)
|
||||
}
|
||||
}
|
||||
|
||||
void Terrain::Draw(RenderContext& renderContext)
|
||||
{
|
||||
const DrawPass drawModes = DrawModes & renderContext.View.Pass;
|
||||
if (drawModes == DrawPass::None)
|
||||
return;
|
||||
PROFILE_CPU();
|
||||
if (DrawSetup(renderContext))
|
||||
return;
|
||||
HashSet<TerrainChunk*, RendererAllocation> drawnChunks;
|
||||
DrawImpl(renderContext, drawnChunks);
|
||||
}
|
||||
|
||||
bool Terrain::DrawSetup(RenderContext& renderContext)
|
||||
{
|
||||
// Special drawing modes
|
||||
|
||||
@@ -462,7 +462,6 @@ private:
|
||||
public:
|
||||
// [PhysicsColliderActor]
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
#if USE_EDITOR
|
||||
void OnDebugDrawSelected() override;
|
||||
#endif
|
||||
|
||||
@@ -119,8 +119,9 @@ bool SpriteRender::HasContentLoaded() const
|
||||
return (Material == nullptr || Material->IsLoaded()) && (Image == nullptr || Image->IsLoaded());
|
||||
}
|
||||
|
||||
void SpriteRender::Draw(RenderContext& renderContext)
|
||||
void SpriteRender::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSDF || renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas)
|
||||
return;
|
||||
if (!Material || !Material->IsLoaded() || !_quadModel || !_quadModel->IsLoaded())
|
||||
@@ -145,7 +146,7 @@ void SpriteRender::Draw(RenderContext& renderContext)
|
||||
view.GetWorldMatrix(_transform, m2);
|
||||
Matrix::Multiply(m1, m2, world);
|
||||
}
|
||||
model->LODs[0].Draw(renderContext, _materialInstance, world, GetStaticFlags(), false, DrawModes, GetPerInstanceRandom(), SortOrder);
|
||||
model->LODs[0].Draw(renderContextBatch, _materialInstance, world, GetStaticFlags(), false, DrawModes, GetPerInstanceRandom(), SortOrder);
|
||||
}
|
||||
|
||||
void SpriteRender::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
|
||||
@@ -98,7 +98,7 @@ private:
|
||||
public:
|
||||
// [Actor]
|
||||
bool HasContentLoaded() const override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
void OnLayerChanged() override;
|
||||
|
||||
@@ -362,54 +362,54 @@ bool TextRender::HasContentLoaded() const
|
||||
return (Material == nullptr || Material->IsLoaded()) && (Font == nullptr || Font->IsLoaded());
|
||||
}
|
||||
|
||||
void TextRender::Draw(RenderContext& renderContext)
|
||||
void TextRender::Draw(RenderContextBatch& renderContextBatch)
|
||||
{
|
||||
const RenderContext& renderContext = renderContextBatch.GetMainContext();
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSDF)
|
||||
return; // TODO: Text rendering to Global SDF
|
||||
if (renderContext.View.Pass == DrawPass::GlobalSurfaceAtlas)
|
||||
return; // TODO: Text rendering to Global Surface Atlas
|
||||
if (_isDirty)
|
||||
UpdateLayout();
|
||||
if (_vb.Data.IsEmpty())
|
||||
return;
|
||||
Matrix world;
|
||||
renderContext.View.GetWorldMatrix(_transform, world);
|
||||
auto drawState = renderContext.Buffers->GetGeometryDrawState(&GetScene()->Rendering, _sceneRenderingKey, this);
|
||||
GEOMETRY_DRAW_STATE_EVENT_BEGIN(drawState, world);
|
||||
|
||||
const DrawPass drawModes = DrawModes & renderContext.View.Pass & renderContext.View.GetShadowsDrawPassMask(ShadowsMode);
|
||||
if (_vb.Data.Count() > 0 && drawModes != DrawPass::None)
|
||||
// Flush buffers
|
||||
if (_buffersDirty)
|
||||
{
|
||||
// Flush buffers
|
||||
if (_buffersDirty)
|
||||
{
|
||||
_buffersDirty = false;
|
||||
_ib.Flush();
|
||||
_vb.Flush();
|
||||
}
|
||||
_buffersDirty = false;
|
||||
_ib.Flush();
|
||||
_vb.Flush();
|
||||
}
|
||||
|
||||
// Setup draw call
|
||||
DrawCall drawCall;
|
||||
drawCall.World = world;
|
||||
drawCall.ObjectPosition = drawCall.World.GetTranslation();
|
||||
drawCall.ObjectRadius = (float)_sphere.Radius;
|
||||
drawCall.Surface.GeometrySize = _localBox.GetSize();
|
||||
drawCall.Surface.PrevWorld = drawState ? drawState->PrevWorld : world;
|
||||
drawCall.PerInstanceRandom = GetPerInstanceRandom();
|
||||
drawCall.SetStencilValue(_layer);
|
||||
drawCall.Geometry.IndexBuffer = _ib.GetBuffer();
|
||||
drawCall.Geometry.VertexBuffers[0] = _vb.GetBuffer();
|
||||
drawCall.InstanceCount = 1;
|
||||
// Setup draw call
|
||||
DrawCall drawCall;
|
||||
drawCall.World = world;
|
||||
drawCall.ObjectPosition = drawCall.World.GetTranslation();
|
||||
drawCall.ObjectRadius = (float)_sphere.Radius;
|
||||
drawCall.Surface.GeometrySize = _localBox.GetSize();
|
||||
drawCall.Surface.PrevWorld = drawState ? drawState->PrevWorld : world;
|
||||
drawCall.PerInstanceRandom = GetPerInstanceRandom();
|
||||
drawCall.SetStencilValue(_layer);
|
||||
drawCall.Geometry.IndexBuffer = _ib.GetBuffer();
|
||||
drawCall.Geometry.VertexBuffers[0] = _vb.GetBuffer();
|
||||
drawCall.InstanceCount = 1;
|
||||
|
||||
// Submit draw calls
|
||||
for (const auto& e : _drawChunks)
|
||||
{
|
||||
const DrawPass chunkDrawModes = drawModes & e.Material->GetDrawModes();
|
||||
if (chunkDrawModes == DrawPass::None)
|
||||
continue;
|
||||
drawCall.Draw.IndicesCount = e.IndicesCount;
|
||||
drawCall.Draw.StartIndex = e.StartIndex;
|
||||
drawCall.Material = e.Material;
|
||||
renderContext.List->AddDrawCall(renderContext, chunkDrawModes, GetStaticFlags(), drawCall, true, SortOrder);
|
||||
}
|
||||
// Submit draw calls
|
||||
const DrawPass drawModes = DrawModes & renderContext.View.GetShadowsDrawPassMask(ShadowsMode);
|
||||
for (const auto& e : _drawChunks)
|
||||
{
|
||||
const DrawPass chunkDrawModes = drawModes & e.Material->GetDrawModes();
|
||||
if (chunkDrawModes == DrawPass::None)
|
||||
continue;
|
||||
drawCall.Draw.IndicesCount = e.IndicesCount;
|
||||
drawCall.Draw.StartIndex = e.StartIndex;
|
||||
drawCall.Material = e.Material;
|
||||
renderContext.List->AddDrawCall(renderContextBatch, chunkDrawModes, GetStaticFlags(), ShadowsMode, _sphere, drawCall, true, SortOrder);
|
||||
}
|
||||
|
||||
GEOMETRY_DRAW_STATE_EVENT_END(drawState, world);
|
||||
|
||||
@@ -160,7 +160,7 @@ private:
|
||||
public:
|
||||
// [Actor]
|
||||
bool HasContentLoaded() const override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void Draw(RenderContextBatch& renderContextBatch) override;
|
||||
#if USE_EDITOR
|
||||
void OnDebugDrawSelected() override;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user