1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #pragma once |
4 | |
5 | #include "BsPrerequisites.h" |
6 | #include "Math/BsVector3.h" |
7 | #include "RenderAPI/BsSubMesh.h" |
8 | |
9 | namespace bs { namespace ct |
10 | { |
11 | /** @addtogroup Renderer-Engine-Internal |
12 | * @{ |
13 | */ |
14 | |
15 | /** |
16 | * Controls if and how a render queue groups renderable objects by material in order to reduce number of state changes. |
17 | */ |
18 | enum class StateReduction |
19 | { |
20 | None, /**< No grouping based on material will be done. */ |
21 | Material, /**< Elements will be grouped by material first, by distance second. */ |
22 | Distance /**< Elements will be grouped by distance first, material second. */ |
23 | }; |
24 | |
25 | /** Contains data needed for performing a single rendering pass. */ |
26 | struct RenderQueueElement |
27 | { |
28 | const RenderElement* renderElem = nullptr; |
29 | UINT32 passIdx = 0; |
30 | UINT32 techniqueIdx = 0; |
31 | bool applyPass = true; |
32 | }; |
33 | |
34 | /** |
35 | * Render objects determines rendering order of objects contained within it. Rendering order is determined by object |
36 | * material, and can influence rendering of transparent or opaque objects, or be used to improve performance by grouping |
37 | * similar objects together. |
38 | */ |
39 | class BS_EXPORT RenderQueue |
40 | { |
41 | /** Data used for renderable element sorting. Represents a single pass for a single mesh. */ |
42 | struct SortableElement |
43 | { |
44 | UINT32 seqIdx; |
45 | INT32 priority; |
46 | float distFromCamera; |
47 | UINT32 shaderId; |
48 | UINT32 techniqueIdx; |
49 | UINT32 passIdx; |
50 | }; |
51 | |
52 | public: |
53 | RenderQueue(StateReduction grouping = StateReduction::Distance); |
54 | virtual ~RenderQueue() = default; |
55 | |
56 | /** |
57 | * Adds a new entry to the render queue. |
58 | * |
59 | * @param[in] element Renderable element to add to the queue. |
60 | * @param[in] distFromCamera Distance of this object from the camera. Used for distance sorting. |
61 | * @param[in] techniqueIdx Index of the technique within @p element's material that's to be used to render the |
62 | * element with. |
63 | */ |
64 | void add(const RenderElement* element, float distFromCamera, UINT32 techniqueIdx); |
65 | |
66 | /** Clears all render operations from the queue. */ |
67 | void clear(); |
68 | |
69 | /** Sorts all the render operations using user-defined rules. */ |
70 | virtual void sort(); |
71 | |
72 | /** Returns a list of sorted render elements. Caller must ensure sort() is called before this method. */ |
73 | const Vector<RenderQueueElement>& getSortedElements() const; |
74 | |
75 | /** |
76 | * Controls if and how a render queue groups renderable objects by material in order to reduce number of state |
77 | * changes. |
78 | */ |
79 | void setStateReduction(StateReduction mode) { mStateReductionMode = mode; } |
80 | |
81 | protected: |
82 | /** Callback used for sorting elements with no material grouping. */ |
83 | static bool elementSorterNoGroup(UINT32 aIdx, UINT32 bIdx, const Vector<SortableElement>& lookup); |
84 | |
85 | /** Callback used for sorting elements with preferred material grouping. */ |
86 | static bool elementSorterPreferGroup(UINT32 aIdx, UINT32 bIdx, const Vector<SortableElement>& lookup); |
87 | |
88 | /** Callback used for sorting elements with material grouping after sorting. */ |
89 | static bool elementSorterPreferDistance(UINT32 aIdx, UINT32 bIdx, const Vector<SortableElement>& lookup); |
90 | |
91 | Vector<SortableElement> mSortableElements; |
92 | Vector<UINT32> mSortableElementIdx; |
93 | Vector<const RenderElement*> mElements; |
94 | |
95 | Vector<RenderQueueElement> mSortedRenderElements; |
96 | StateReduction mStateReductionMode; |
97 | }; |
98 | |
99 | /** @} */ |
100 | }} |