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
9namespace 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}}