Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
RenderingComponent.h
Go to the documentation of this file.
1/*
2Copyright (c) 2018 DIVIDE-Studio
3Copyright (c) 2009 Ionut Cava
4
5This file is part of DIVIDE Framework.
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of
8this software
9and associated documentation files (the "Software"), to deal in the Software
10without restriction,
11including without limitation the rights to use, copy, modify, merge, publish,
12distribute, sublicense,
13and/or sell copies of the Software, and to permit persons to whom the Software
14is furnished to do so,
15subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED,
22INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
23PARTICULAR PURPOSE AND NONINFRINGEMENT.
24IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25DAMAGES OR OTHER LIABILITY,
26WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27CONNECTION WITH THE SOFTWARE
28OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30*/
31
32#pragma once
33#ifndef DVD_RENDERING_COMPONENT_H_
34#define DVD_RENDERING_COMPONENT_H_
35
36#include "SGNComponent.h"
37
44
45namespace Divide {
46struct NodeMaterialData;
47
48class Sky;
49class SubMesh;
50class Material;
51class GFXDevice;
52class RenderBin;
53class RenderPass;
54class WaterPlane;
55class RenderQueue;
56class SceneGraphNode;
57class ParticleEmitter;
58class RenderPassExecutor;
59class SceneEnvironmentProbePool;
60class EnvironmentProbeComponent;
61
62struct RenderBinItem;
63struct Configuration;
64
66
68
69namespace Attorney {
70 class RenderingCompRenderPass;
71 class RenderingCompGFXDevice;
72 class RenderingCompRenderBin;
73 class RenderingCompRenderPassExecutor;
74 class RenderingComponentSGN;
75}
76
78{
81};
82
84 explicit RenderCbkParams(GFXDevice& context,
85 const SceneGraphNode* sgn,
86 const SceneRenderState& sceneRenderState,
87 const RenderTargetID& renderTarget,
88 const U16 passIndex,
89 const U8 passVariant,
90 Camera* camera) noexcept;
91
93 const SceneGraphNode* _sgn{ nullptr };
96
97 Camera* _camera{ nullptr };
100};
101
103
104using DrawCommandContainer = eastl::fixed_vector<IndirectIndexedDrawCommand, Config::MAX_VISIBLE_NODES, false>;
105
107 friend class Attorney::RenderingCompRenderPass;
108 friend class Attorney::RenderingCompGFXDevice;
109 friend class Attorney::RenderingCompRenderBin;
110 friend class Attorney::RenderingCompRenderPassExecutor;
111 friend class Attorney::RenderingComponentSGN;
112
113 public:
114 static constexpr U8 MAX_LOD_LEVEL = 4u;
115
116 enum class RenderOptions : U16 {
119 RENDER_SKELETON = toBit(3),
120 RENDER_SELECTION = toBit(4),
121 RENDER_AXIS = toBit(5),
122 CAST_SHADOWS = toBit(6),
123 RECEIVE_SHADOWS = toBit(7),
124 IS_VISIBLE = toBit(8)
125 };
126
128 {
131 };
132
133 public:
134 explicit RenderingComponent(SceneGraphNode* parentSGN, PlatformContext& context);
135 ~RenderingComponent() override;
136
138 [[nodiscard]] bool renderOptionEnabled(RenderOptions option) const noexcept;
139 void toggleRenderOption(RenderOptions option, bool state, bool recursive = true);
140
141 void setMinRenderRange(F32 minRange) noexcept;
142 void setMaxRenderRange(F32 maxRange) noexcept;
143 inline void setRenderRange(const F32 minRange, const F32 maxRange) noexcept { setMinRenderRange(minRange); setMaxRenderRange(maxRange); }
144 [[nodiscard]] inline vec2<F32> renderRange() const noexcept { return _renderRange; }
145
146 [[nodiscard]] inline bool lodLocked(const RenderStage stage) const noexcept { return _lodLockLevels[to_base(stage)].first; }
147 inline void lockLoD(const U8 level) { _lodLockLevels.fill({ true, level }); }
148 inline void unlockLoD() { _lodLockLevels.fill({ false, U8_ZERO }); }
149 inline void lockLoD(const RenderStage stage, U8 level) noexcept { _lodLockLevels[to_base(stage)] = { true, level }; }
150 inline void unlockLoD(const RenderStage stage) noexcept { _lodLockLevels[to_base(stage)] = { false, U8_ZERO }; }
151 [[nodiscard]] U8 getLoDLevel(RenderStage renderStage) const noexcept;
152 [[nodiscard]] U8 getLoDLevel(const F32 distSQtoCenter, RenderStage renderStage, vec4<U16> lodThresholds);
153 void setLoDIndexOffset(U8 lodIndex, size_t indexOffset, size_t indexCount) noexcept;
154
155 void getMaterialData(NodeMaterialData& dataOut) const;
156 void rebuildMaterial();
157
158 void instantiateMaterial(Handle<Material> material);
159 [[nodiscard]] inline Handle<Material> getMaterialInstance() const noexcept { return _materialInstance; }
160
161 [[nodiscard]] inline DrawCommands& drawCommands() noexcept { return _drawCommands; }
162
163 inline void setReflectionCallback(const RenderCallback& cbk, const ReflectorType reflectType) { _reflectionCallback = cbk; _reflectorType = reflectType; }
164 inline void setRefractionCallback(const RenderCallback& cbk, const RefractorType refractType) { _refractionCallback = cbk; _refractorType = refractType; }
165
166 [[nodiscard]] bool canDraw(const RenderStagePass& renderStagePass);
167
168 void drawDebugAxis();
169 void drawSelectionGizmo();
170 void drawSkeleton();
171 void drawBounds(bool AABB, bool OBB, bool Sphere);
172
173 PROPERTY_R(bool, showAxis, false);
174 PROPERTY_R(bool, receiveShadows, false);
175 PROPERTY_RW(bool, primitiveRestartRequired, false);
176 PROPERTY_R(bool, castsShadows, false);
177 PROPERTY_RW(bool, occlusionCull, true);
178 PROPERTY_RW(F32, dataFlag, 1.0f);
179 PROPERTY_R_IW(bool, isInstanced, false);
180 PROPERTY_R_IW(bool, rebuildDrawCommands, false);
181
182 protected:
183 void getCommandBuffer(RenderPackage* const pkg, GFX::CommandBuffer& bufferInOut);
184 [[nodiscard]] RenderPackage& getDrawPackage(const RenderStagePass& renderStagePass);
185 [[nodiscard]] U8 getLoDLevelInternal(const F32 distSQtoCenter, RenderStage renderStage, vec4<U16> lodThresholds);
186
187 void toggleBoundsDraw(bool showAABB, bool showBS, bool showOBB, bool recursive);
188 void onRenderOptionChanged(RenderOptions option, bool state);
189 void clearDrawPackages(const RenderStage stage, const RenderPassType pass);
190 void clearDrawPackages();
191 void updateReflectRefractDescriptors(bool reflectState, bool refractState);
192
193 [[nodiscard]] bool hasDrawCommands() noexcept;
194 void retrieveDrawCommands(const RenderStagePass& stagePass, const U32 cmdOffset, DrawCommandContainer& cmdsInOut);
195
197 void postRender(const SceneRenderState& sceneRenderState,
198 const RenderStagePass& renderStagePass,
199 GFX::CommandBuffer& bufferInOut);
200
201 bool prepareDrawPackage(const CameraSnapshot& cameraSnapshot,
202 const SceneRenderState& sceneRenderState,
203 const RenderStagePass& renderStagePass,
204 GFX::MemoryBarrierCommand& postDrawMemCmd,
205 bool refreshData);
206
207 // This returns false if the node is not reflective, otherwise it generates a new reflection cube map
208 // and saves it in the appropriate material slot
209 [[nodiscard]] bool updateReflection(U16 reflectionIndex,
210 bool inBudget,
211 Camera* camera,
212 const SceneRenderState& renderState,
213 GFX::CommandBuffer& bufferInOut,
214 GFX::MemoryBarrierCommand& memCmdInOut);
215
216 [[nodiscard]] bool updateRefraction(U16 refractionIndex,
217 bool inBudget,
218 Camera* camera,
219 const SceneRenderState& renderState,
220 GFX::CommandBuffer& bufferInOut,
221 GFX::MemoryBarrierCommand& memCmdInOut);
222
223 void updateNearestProbes(const vec3<F32>& position);
224
225 void onParentUsageChanged(NodeUsageContext context) const;
226 void OnData(const ECS::CustomEvent& data) override;
227
228 protected:
229 GFXDevice& _gfxContext;
230 const Configuration& _config;
231
233 {
235 U16 _index{ 0u };
236 };
237
242
244
245 Handle<Material> _materialInstance{ INVALID_HANDLE<Material> };
246 RenderCallback _reflectionCallback{};
247 RenderCallback _refractionCallback{};
248
252
254
256 std::pair<Handle<Texture>, SamplerDescriptor> _reflectionPlanar{INVALID_HANDLE<Texture>, {}};
257 std::pair<Handle<Texture>, SamplerDescriptor> _refractionPlanar{INVALID_HANDLE<Texture>, {}};
258
259 std::array<U8, to_base(RenderStage::COUNT)> _lodLevels{};
260 std::array<std::pair<size_t, size_t>, MAX_LOD_LEVEL> _lodIndexOffsets{};
261 std::array<std::pair<bool, U8>, to_base(RenderStage::COUNT)> _lodLockLevels{};
262 std::array<PackagesPerPassType, to_base(RenderStage::COUNT)> _renderPackages{};
263
265
266 U32 _indirectionBufferEntry{ U32_MAX };
267 U32 _renderMask{ 0u };
268 U16 _reflectionProbeIndex{ 0u };
269
272
273 bool _selectionGizmoDirty{ true };
274 bool _drawAABB{ false };
275 bool _drawOBB{ false };
276 bool _drawBS{ false };
277 bool _updateReflection{ false };
278 bool _updateRefraction{ false };
279 U32 _materialUpdateMask{ to_base(MaterialUpdateResult::OK) };
280
281END_COMPONENT(Rendering);
282
283namespace Attorney {
288 [[nodiscard]] static bool updateReflection(RenderingComponent& renderable,
289 const U16 reflectionIndex,
290 const bool inBudget,
291 Camera* camera,
292 const SceneRenderState& renderState,
293 GFX::CommandBuffer& bufferInOut,
294 GFX::MemoryBarrierCommand& memCmdInOut)
295 {
296 return renderable.updateReflection(reflectionIndex, inBudget, camera, renderState, bufferInOut, memCmdInOut);
297 }
298
301 [[nodiscard]] static bool updateRefraction(RenderingComponent& renderable,
302 const U16 refractionIndex,
303 const bool inBudget,
304 Camera* camera,
305 const SceneRenderState& renderState,
306 GFX::CommandBuffer& bufferInOut,
307 GFX::MemoryBarrierCommand& memCmdInOut)
308 {
309 return renderable.updateRefraction(refractionIndex, inBudget, camera, renderState, bufferInOut, memCmdInOut);
310 }
311
312 [[nodiscard]] static bool prepareDrawPackage(RenderingComponent& renderable,
313 const CameraSnapshot& cameraSnapshot,
314 const SceneRenderState& sceneRenderState,
315 RenderStagePass renderStagePass,
316 GFX::MemoryBarrierCommand& postDrawMemCmd,
317 const bool refreshData)
318 {
319 return renderable.prepareDrawPackage(cameraSnapshot, sceneRenderState, renderStagePass, postDrawMemCmd, refreshData);
320 }
321
322 [[nodiscard]] static bool hasDrawCommands(RenderingComponent& renderable) noexcept {
323 return renderable.hasDrawCommands();
324 }
325
326 static void retrieveDrawCommands(RenderingComponent& renderable, const RenderStagePass stagePass, const U32 cmdOffset, DrawCommandContainer& cmdsInOut) {
327 renderable.retrieveDrawCommands(stagePass, cmdOffset, cmdsInOut);
328 }
329
330 friend class Divide::RenderPass;
333};
334
336 static void postRender(RenderingComponent* renderable,
337 const SceneRenderState& sceneRenderState,
338 const RenderStagePass renderStagePass,
339 GFX::CommandBuffer& bufferInOut)
340 {
341 renderable->postRender(sceneRenderState, renderStagePass, bufferInOut);
342 }
343
344 [[nodiscard]] static RenderPackage& getDrawPackage(RenderingComponent* renderable, const RenderStagePass renderStagePass)
345 {
346 return renderable->getDrawPackage(renderStagePass);
347 }
348
349 [[nodiscard]] static size_t getStateHash( RenderingComponent* renderable, const RenderStagePass renderStagePass )
350 {
351 const RenderPackage& pkg = getDrawPackage( renderable, renderStagePass );
352 return pkg.pipelineCmd()._pipeline->stateHash();
353 }
354
355 friend class Divide::RenderBin;
357};
358
360
361 static void setIndirectionBufferEntry(RenderingComponent* renderable, const U32 indirectionBufferEntry) noexcept {
362 renderable->_indirectionBufferEntry = indirectionBufferEntry;
363 }
364
365 [[nodiscard]] static U32 getIndirectionBufferEntry(RenderingComponent* const renderable) noexcept {
366 return renderable->_indirectionBufferEntry;
367 }
368
369 static void getCommandBuffer(RenderingComponent* renderable, RenderPackage* const pkg, GFX::CommandBuffer& bufferInOut) {
370 renderable->getCommandBuffer(pkg, bufferInOut);
371 }
372
374};
375
377 static void onParentUsageChanged(const RenderingComponent& comp, const NodeUsageContext context) {
378 comp.onParentUsageChanged(context);
379 }
380
382};
383} // namespace Attorney
384} // namespace Divide
385
386#endif //DVD_RENDERING_COMPONENT_H_
#define TYPEDEF_SMART_POINTERS_FOR_TYPE(T)
#define END_COMPONENT(Name)
Definition: SGNComponent.h:223
#define BEGIN_COMPONENT(Name, Enum)
Definition: SGNComponent.h:215
static void postRender(RenderingComponent *renderable, const SceneRenderState &sceneRenderState, const RenderStagePass renderStagePass, GFX::CommandBuffer &bufferInOut)
static RenderPackage & getDrawPackage(RenderingComponent *renderable, const RenderStagePass renderStagePass)
static size_t getStateHash(RenderingComponent *renderable, const RenderStagePass renderStagePass)
static void getCommandBuffer(RenderingComponent *renderable, RenderPackage *const pkg, GFX::CommandBuffer &bufferInOut)
static void setIndirectionBufferEntry(RenderingComponent *renderable, const U32 indirectionBufferEntry) noexcept
static U32 getIndirectionBufferEntry(RenderingComponent *const renderable) noexcept
static void retrieveDrawCommands(RenderingComponent &renderable, const RenderStagePass stagePass, const U32 cmdOffset, DrawCommandContainer &cmdsInOut)
static bool hasDrawCommands(RenderingComponent &renderable) noexcept
static bool updateRefraction(RenderingComponent &renderable, const U16 refractionIndex, const bool inBudget, Camera *camera, const SceneRenderState &renderState, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
static bool updateReflection(RenderingComponent &renderable, const U16 reflectionIndex, const bool inBudget, Camera *camera, const SceneRenderState &renderState, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
static bool prepareDrawPackage(RenderingComponent &renderable, const CameraSnapshot &cameraSnapshot, const SceneRenderState &sceneRenderState, RenderStagePass renderStagePass, GFX::MemoryBarrierCommand &postDrawMemCmd, const bool refreshData)
static void onParentUsageChanged(const RenderingComponent &comp, const NodeUsageContext context)
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
Definition: GFXDevice.h:215
This class contains a list of "RenderBinItem"'s and stores them sorted depending on designation.
Definition: RenderBin.h:112
This class manages all of the RenderBins and renders them in the correct order.
Definition: RenderQueue.h:49
void setReflectionCallback(const RenderCallback &cbk, const ReflectorType reflectType)
void unlockLoD(const RenderStage stage) noexcept
void setRefractionCallback(const RenderCallback &cbk, const RefractorType refractType)
std::array< PackagesPerVariant, to_base(RenderPassType::COUNT)> PackagesPerPassType
PROPERTY_R(bool, showAxis, false)
IM::LineDescriptor _skeletonLinesDescriptor
PROPERTY_RW(F32, dataFlag, 1.0f)
std::array< PackagesPerPassIndex, to_base(RenderStagePass::VariantType::COUNT)> PackagesPerVariant
PROPERTY_R_IW(bool, isInstanced, false)
DrawCommands & drawCommands() noexcept
vector< PackageEntry > PackagesPerIndex
RenderPackage & getDrawPackage(const RenderStagePass &renderStagePass)
bool updateRefraction(U16 refractionIndex, bool inBudget, Camera *camera, const SceneRenderState &renderState, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
vec2< F32 > renderRange() const noexcept
PROPERTY_RW(bool, primitiveRestartRequired, false)
IM::OBBDescriptor _selectionGizmoDescriptor
std::array< PackagesPerIndex, to_base(RenderStagePass::PassIndex::COUNT)> PackagesPerPassIndex
void setRenderRange(const F32 minRange, const F32 maxRange) noexcept
void lockLoD(const U8 level)
void retrieveDrawCommands(const RenderStagePass &stagePass, const U32 cmdOffset, DrawCommandContainer &cmdsInOut)
void getCommandBuffer(RenderPackage *const pkg, GFX::CommandBuffer &bufferInOut)
bool lodLocked(const RenderStage stage) const noexcept
PROPERTY_RW(bool, occlusionCull, true)
PROPERTY_R(bool, receiveShadows, false)
PROPERTY_R(bool, castsShadows, false)
PROPERTY_R_IW(bool, rebuildDrawCommands, false)
bool prepareDrawPackage(const CameraSnapshot &cameraSnapshot, const SceneRenderState &sceneRenderState, const RenderStagePass &renderStagePass, GFX::MemoryBarrierCommand &postDrawMemCmd, bool refreshData)
void lockLoD(const RenderStage stage, U8 level) noexcept
IM::LineDescriptor _axisGizmoLinesDescriptor
void onParentUsageChanged(NodeUsageContext context) const
Handle< Material > getMaterialInstance() const noexcept
bool updateReflection(U16 reflectionIndex, bool inBudget, Camera *camera, const SceneRenderState &renderState, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
void postRender(const SceneRenderState &sceneRenderState, const RenderStagePass &renderStagePass, GFX::CommandBuffer &bufferInOut)
Called after the parent node was rendered.
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
NodeUsageContext
Usage context affects lighting, navigation, physics, etc.
Definition: SceneNodeFwd.h:41
DELEGATE_STD< Ret, Args... > DELEGATE
void OnData(const ECS::CustomEvent &data) override
uint8_t U8
std::shared_mutex SharedMutex
Definition: SharedMutex.h:43
eastl::vector< Type > vector
Definition: Vector.h:42
uint16_t U16
DELEGATE< void, RenderPassManager *, RenderCbkParams &, GFX::CommandBuffer &, GFX::MemoryBarrierCommand & > RenderCallback
constexpr U32 U32_MAX
eastl::fixed_vector< GenericDrawCommand, 1, true > GenericDrawCommandContainer
vector< EnvironmentProbeComponent * > EnvironmentProbeList
U32 RenderTargetID
uint32_t U32
constexpr U8 U8_ZERO
constexpr T toBit(const T X)
Converts an arbitrary positive integer value to a bitwise value used for masks.
eastl::fixed_vector< IndirectIndexedDrawCommand, Config::MAX_VISIBLE_NODES, false > DrawCommandContainer
constexpr auto to_base(const Type value) -> Type
const RenderTargetID & _renderTarget
const SceneGraphNode * _sgn
const SceneRenderState & _sceneRenderState
GenericDrawCommand _cmd
RenderPackage _package