Refactor Actor::Draw to use only variant with RenderContextBatch to simplify rendering code

This commit is contained in:
2026-08-20 22:50:32 +02:00
parent 3090ad5e20
commit dfb0db0b70
49 changed files with 227 additions and 272 deletions
+18
View File
@@ -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>
+25 -32
View File
@@ -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)
-1
View File
@@ -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;
+36
View File
@@ -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);
+15
View File
@@ -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>
-8
View File
@@ -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
+1 -7
View File
@@ -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);
+9 -58
View File
@@ -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;
+2 -1
View File
@@ -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
+1 -1
View File
@@ -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;
+2 -1
View File
@@ -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) &&
+1 -1
View File
@@ -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;
+2 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+2 -1
View File
@@ -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
+1 -1
View File
@@ -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;
+2 -1
View File
@@ -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;
+1 -1
View File
@@ -107,7 +107,7 @@ private:
public:
// [Light]
void Draw(RenderContext& renderContext) override;
void Draw(RenderContextBatch& renderContextBatch) override;
#if USE_EDITOR
void OnDebugDrawSelected() override;
#endif
+2 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+6 -6
View File
@@ -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);
}
}
}
+1 -1
View File
@@ -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;
+2 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+9 -45
View File
@@ -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);
}
-1
View File
@@ -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;
+1 -1
View File
@@ -276,7 +276,7 @@ void SceneRendering::DrawActorsJob(int32 i)
FOR_EACH_BATCH_ACTOR
if (CHECK_ACTOR_SINGLE_FRUSTUM)
{
DRAW_ACTOR(mainContext);
DRAW_ACTOR(*_drawBatch);
}
}
}
+5 -13
View File
@@ -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);
-1
View File
@@ -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;
-6
View File
@@ -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
-1
View File
@@ -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
+1 -1
View File
@@ -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)
{
+7 -2
View File
@@ -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
View File
@@ -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);
};
-12
View File
@@ -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
-1
View File
@@ -462,7 +462,6 @@ private:
public:
// [PhysicsColliderActor]
void Draw(RenderContextBatch& renderContextBatch) override;
void Draw(RenderContext& renderContext) override;
#if USE_EDITOR
void OnDebugDrawSelected() override;
#endif
+3 -2
View File
@@ -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)
+1 -1
View File
@@ -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;
+33 -33
View File
@@ -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);
+1 -1
View File
@@ -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