// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Delegate.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Core/Math/BoundingSphere.h" #include "Engine/Core/Math/BoundingFrustum.h" #include "Engine/Level/Actor.h" #include "Engine/Platform/CriticalSection.h" class SceneRenderTask; class SceneRendering; struct PostProcessSettings; struct RenderContext; struct RenderContextBatch; struct RenderView; /// /// Interface for actors that can override the default rendering settings (eg. PostFxVolume actor). /// class FLAXENGINE_API IPostFxSettingsProvider { public: /// /// Collects the settings for rendering of the specified task. /// /// The rendering context. virtual void Collect(RenderContext& renderContext) = 0; /// /// Blends the object settings to the given settings using given weight. /// /// The other settings to blend to. /// The blending weight (normalized to 0-1 range). virtual void Blend(PostProcessSettings& other, float weight) = 0; }; /// /// Interface for objects to plug into Scene Rendering and listen for its evens such as static actors changes which are relevant for drawing cache. /// /// class FLAXENGINE_API ISceneRenderingListener { friend SceneRendering; private: Array> _scenes; public: ~ISceneRenderingListener(); // Starts listening to the scene rendering events. void ListenSceneRendering(SceneRendering* scene); // Events called by Scene Rendering virtual void OnSceneRenderingAddActor(Actor* a) = 0; virtual void OnSceneRenderingUpdateActor(Actor* a, const BoundingSphere& prevBounds) = 0; virtual void OnSceneRenderingRemoveActor(Actor* a) = 0; virtual void OnSceneRenderingClear(SceneRendering* scene) = 0; }; /// /// Scene rendering helper subsystem that boosts the level rendering by providing efficient objects cache and culling implementation. /// class FLAXENGINE_API SceneRendering { #if USE_EDITOR typedef Function PhysicsDebugCallback; typedef Function LightsDebugCallback; friend class ViewportIconsRendererService; #endif public: struct DrawActor { Actor* Actor; uint32 LayerMask; int8 NoCulling : 1; BoundingSphere Bounds; }; /// /// Drawing categories for separate draw stages. /// enum DrawCategory { SceneDraw = 0, SceneDrawAsync, PreRender, PostRender, MAX }; Array Actors[MAX]; Array PostFxProviders; CriticalSection Locker; private: #if USE_EDITOR Array PhysicsDebug; Array LightsDebug; Array ViewportIcons; #endif // Listener - some rendering systems cache state of the scene (eg. in RenderBuffers::CustomBuffer), this extensions allows those systems to invalidate cache and handle scene changes friend ISceneRenderingListener; Array> _listeners; public: /// /// Draws the scene. Performs the optimized actors culling and draw calls submission for the current render pass (defined by the render view). /// /// The rendering context batch. /// The actors category to draw. void Draw(RenderContextBatch& renderContextBatch, DrawCategory category = SceneDraw); /// /// Collects the post fx volumes for the given rendering view. /// /// The rendering context. void CollectPostFxVolumes(RenderContext& renderContext); /// /// Clears this instance data. /// void Clear(); public: void AddActor(Actor* a, int32& key); void UpdateActor(Actor* a, int32& key); void RemoveActor(Actor* a, int32& key); FORCE_INLINE void AddPostFxProvider(IPostFxSettingsProvider* obj) { PostFxProviders.Add(obj); } FORCE_INLINE void RemovePostFxProvider(IPostFxSettingsProvider* obj) { PostFxProviders.Remove(obj); } #if USE_EDITOR template FORCE_INLINE void AddPhysicsDebug(T* obj) { PhysicsDebugCallback f; f.Bind(obj); PhysicsDebug.Add(f); } template void RemovePhysicsDebug(T* obj) { PhysicsDebugCallback f; f.Bind(obj); PhysicsDebug.Remove(f); } template FORCE_INLINE void AddLightsDebug(T* obj) { LightsDebugCallback f; f.Bind(obj); LightsDebug.Add(f); } template void RemoveLightsDebug(T* obj) { LightsDebugCallback f; f.Bind(obj); LightsDebug.Remove(f); } FORCE_INLINE void AddViewportIcon(Actor* obj) { ViewportIcons.Add(obj); } FORCE_INLINE void RemoveViewportIcon(Actor* obj) { ViewportIcons.Remove(obj); } #endif private: Array _drawFrustumsData; DrawActor* _drawListData; int64 _drawListSize; volatile int64 _drawListIndex; RenderContextBatch* _drawBatch; void DrawActorsJob(int32); };