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 "BsCorePrerequisites.h"
6#include "Reflection/BsIReflectable.h"
7#include "CoreThread/BsCoreObject.h"
8
9namespace bs
10{
11 /** @addtogroup RenderAPI
12 * @{
13 */
14
15 /**
16 * Descriptor structured used for initializing DepthStencilState.
17 *
18 * @see DepthStencilState
19 */
20 struct BS_CORE_EXPORT DEPTH_STENCIL_STATE_DESC
21 {
22 bool operator==(const DEPTH_STENCIL_STATE_DESC& rhs) const;
23
24 /**
25 * If enabled, any pixel about to be written will be tested against the depth value currently in the buffer. If the
26 * depth test passes (depending on the set valueand chosen depth comparison function), that pixel is written and
27 * depth is updated (if depth write is enabled).
28 */
29 bool depthReadEnable = true;
30
31 /** If enabled rendering pixels will update the depth buffer value. */
32 bool depthWriteEnable = true;
33
34 /**
35 * Determines what operation should the renderer use when comparing previous and current depth value. If the
36 * operation passes, pixel with the current depth value will be considered visible.
37 */
38 CompareFunction depthComparisonFunc = CMPF_LESS;
39
40 /**
41 * If true then stencil buffer will also be updated when a pixel is written, and pixels will be tested against
42 * the stencil buffer before rendering.
43 */
44 bool stencilEnable = false;
45
46 /** Mask to apply to any value read from the stencil buffer, before applying the stencil comparison function. */
47 UINT8 stencilReadMask = 0xFF;
48
49 /** Mask to apply to any value about to be written in the stencil buffer. */
50 UINT8 stencilWriteMask = 0xFF;
51
52 /** Operation that happens when stencil comparison function fails on a front facing polygon. */
53 StencilOperation frontStencilFailOp = SOP_KEEP;
54
55 /** Operation that happens when stencil comparison function passes but depth test fails on a front facing polygon. */
56 StencilOperation frontStencilZFailOp = SOP_KEEP;
57
58 /** Operation that happens when stencil comparison function passes on a front facing polygon. */
59 StencilOperation frontStencilPassOp = SOP_KEEP;
60
61 /**
62 * Stencil comparison function used for front facing polygons. Stencil buffer will be modified according to
63 * previously set stencil operations depending whether this comparison passes or fails.
64 */
65 CompareFunction frontStencilComparisonFunc = CMPF_ALWAYS_PASS;
66
67 /** Operation that happens when stencil comparison function fails on a back facing polygon. */
68 StencilOperation backStencilFailOp = SOP_KEEP;
69
70 /** Operation that happens when stencil comparison function passes but depth test fails on a back facing polygon. */
71 StencilOperation backStencilZFailOp = SOP_KEEP;
72
73 /** Operation that happens when stencil comparison function passes on a back facing polygon. */
74 StencilOperation backStencilPassOp = SOP_KEEP;
75
76 /**
77 * Stencil comparison function used for back facing polygons. Stencil buffer will be modified according to
78 * previously set stencil operations depending whether this comparison passes or fails.
79 */
80 CompareFunction backStencilComparisonFunc = CMPF_ALWAYS_PASS;
81 };
82
83 /** @cond SPECIALIZATIONS */
84 BS_ALLOW_MEMCPY_SERIALIZATION(DEPTH_STENCIL_STATE_DESC);
85 /** @endcond */
86
87 /** Properties of DepthStencilState. Shared between sim and core thread versions of DepthStencilState. */
88 class BS_CORE_EXPORT DepthStencilProperties
89 {
90 public:
91 DepthStencilProperties(const DEPTH_STENCIL_STATE_DESC& desc);
92
93 /** @copydoc DEPTH_STENCIL_STATE_DESC::depthReadEnable */
94 bool getDepthReadEnable() const { return mData.depthReadEnable; }
95
96 /** @copydoc DEPTH_STENCIL_STATE_DESC::depthWriteEnable */
97 bool getDepthWriteEnable() const { return mData.depthWriteEnable; }
98
99 /** @copydoc DEPTH_STENCIL_STATE_DESC::depthComparisonFunc */
100 CompareFunction getDepthComparisonFunc() const { return mData.depthComparisonFunc; }
101
102 /** @copydoc DEPTH_STENCIL_STATE_DESC::stencilEnable */
103 bool getStencilEnable() const { return mData.stencilEnable; }
104
105 /** @copydoc DEPTH_STENCIL_STATE_DESC::stencilReadMask */
106 UINT8 getStencilReadMask() const { return mData.stencilReadMask; }
107
108 /** @copydoc DEPTH_STENCIL_STATE_DESC::stencilWriteMask */
109 UINT8 getStencilWriteMask() const { return mData.stencilWriteMask; }
110
111 /** @copydoc DEPTH_STENCIL_STATE_DESC::frontStencilFailOp */
112 StencilOperation getStencilFrontFailOp() const { return mData.frontStencilFailOp; }
113
114 /** @copydoc DEPTH_STENCIL_STATE_DESC::frontStencilZFailOp */
115 StencilOperation getStencilFrontZFailOp() const { return mData.frontStencilZFailOp; }
116
117 /** @copydoc DEPTH_STENCIL_STATE_DESC::frontStencilPassOp */
118 StencilOperation getStencilFrontPassOp() const { return mData.frontStencilPassOp; }
119
120 /** @copydoc DEPTH_STENCIL_STATE_DESC::frontStencilComparisonFunc */
121 CompareFunction getStencilFrontCompFunc() const { return mData.frontStencilComparisonFunc; }
122
123 /** @copydoc DEPTH_STENCIL_STATE_DESC::backStencilFailOp */
124 StencilOperation getStencilBackFailOp() const { return mData.backStencilFailOp; }
125
126 /** @copydoc DEPTH_STENCIL_STATE_DESC::backStencilZFailOp */
127 StencilOperation getStencilBackZFailOp() const { return mData.backStencilZFailOp; }
128
129 /** @copydoc DEPTH_STENCIL_STATE_DESC::backStencilPassOp */
130 StencilOperation getStencilBackPassOp() const { return mData.backStencilPassOp; }
131
132 /** @copydoc DEPTH_STENCIL_STATE_DESC::backStencilComparisonFunc */
133 CompareFunction getStencilBackCompFunc() const { return mData.backStencilComparisonFunc; }
134
135 /** Returns the hash value generated from the depth-stencil state properties. */
136 UINT64 getHash() const { return mHash; }
137
138 protected:
139 friend class DepthStencilState;
140 friend class ct::DepthStencilState;
141 friend class DepthStencilStateRTTI;
142
143 DEPTH_STENCIL_STATE_DESC mData;
144 UINT64 mHash;
145 };
146
147 /**
148 * Render system pipeline state that allows you to modify how an object is rendered. More exactly this state allows to
149 * you to control how are depth and stencil buffers modified upon rendering.
150 *
151 * @note Depth stencil states are immutable. Sim thread only.
152 */
153 class BS_CORE_EXPORT DepthStencilState : public IReflectable, public CoreObject
154 {
155 public:
156 virtual ~DepthStencilState() = default;
157
158 /** Returns information about the depth stencil state. */
159 const DepthStencilProperties& getProperties() const;
160
161 /** Retrieves a core implementation of a sampler state usable only from the core thread. */
162 SPtr<ct::DepthStencilState> getCore() const;
163
164 /** Creates a new depth stencil state using the specified depth stencil state description structure. */
165 static SPtr<DepthStencilState> create(const DEPTH_STENCIL_STATE_DESC& desc);
166
167 /** Returns the default depth stencil state that you may use when no other is available. */
168 static const SPtr<DepthStencilState>& getDefault();
169
170 /** Generates a hash value from a depth-stencil state descriptor. */
171 static UINT64 generateHash(const DEPTH_STENCIL_STATE_DESC& desc);
172
173 protected:
174 friend class RenderStateManager;
175
176 DepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc);
177
178 /** @copydoc CoreObject::createCore */
179 SPtr<ct::CoreObject> createCore() const override;
180
181 DepthStencilProperties mProperties;
182 mutable UINT32 mId;
183
184 /************************************************************************/
185 /* RTTI */
186 /************************************************************************/
187
188 public:
189 friend class DepthStencilStateRTTI;
190 static RTTITypeBase* getRTTIStatic();
191 RTTITypeBase* getRTTI() const override;
192 };
193
194 /** @} */
195
196 namespace ct
197 {
198 /** @addtogroup RenderAPI-Internal
199 * @{
200 */
201
202 /**
203 * Core thread version of bs::DepthStencilState.
204 *
205 * @note Core thread.
206 */
207 class BS_CORE_EXPORT DepthStencilState : public CoreObject
208 {
209 public:
210 virtual ~DepthStencilState();
211
212 /** Returns information about the depth stencil state. */
213 const DepthStencilProperties& getProperties() const;
214
215 /** Returns a unique state ID. Only the lowest 10 bits are used. */
216 UINT32 getId() const { return mId; }
217
218 /** Creates a new depth stencil state using the specified depth stencil state description structure. */
219 static SPtr<DepthStencilState> create(const DEPTH_STENCIL_STATE_DESC& desc);
220
221 /** Returns the default depth stencil state that you may use when no other is available. */
222 static const SPtr<DepthStencilState>& getDefault();
223
224 protected:
225 friend class RenderStateManager;
226
227 DepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc, UINT32 id);
228
229 /** @copydoc CoreObject::initialize */
230 void initialize() override;
231
232 /** Creates any API-specific state objects. */
233 virtual void createInternal() { }
234
235 DepthStencilProperties mProperties;
236 UINT32 mId;
237 };
238
239 /** @} */
240 }
241}
242
243/** @cond STDLIB */
244/** @addtogroup RenderAPI
245 * @{
246 */
247
248namespace std
249{
250/** Hash value generator for DEPTH_STENCIL_STATE_DESC. */
251template<>
252struct hash<bs::DEPTH_STENCIL_STATE_DESC>
253{
254 size_t operator()(const bs::DEPTH_STENCIL_STATE_DESC& value) const
255 {
256 return (size_t)bs::DepthStencilState::generateHash(value);
257 }
258};
259}
260
261/** @} */
262/** @endcond */
263