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 /** Structure that describes pipeline rasterizer state. Used for initializing a RasterizerState. */
16 struct BS_CORE_EXPORT RASTERIZER_STATE_DESC
17 {
18 bool operator==(const RASTERIZER_STATE_DESC& rhs) const;
19
20 /** Polygon mode allows you to draw polygons as solid objects or as wireframe by just drawing their edges. */
21 PolygonMode polygonMode = PM_SOLID;
22
23 /**
24 * Sets vertex winding order. Faces that contain vertices with this order will be culled and not rasterized. Used
25 * primarily for saving cycles by not rendering backfacing faces.
26 */
27 CullingMode cullMode = CULL_COUNTERCLOCKWISE;
28
29 /**
30 * Represents a constant depth bias that will offset the depth values of new pixels by the specified amount.
31 *
32 * @note This is useful if you want to avoid z fighting for objects at the same or similar depth.
33 */
34 float depthBias = 0;
35
36 /** Maximum depth bias value. */
37 float depthBiasClamp = 0.0f;
38
39 /**
40 * Represents a dynamic depth bias that increases as the slope of the rendered polygons surface increases.
41 * Resulting value offsets depth values of new pixels. This offset will be added on top of the constant depth bias.
42 *
43 * @note This is useful if you want to avoid z fighting for objects at the same or similar depth.
44 */
45 float slopeScaledDepthBias = 0.0f;
46
47 /**
48 * If true, clipping of polygons past the far Z plane is enabled. This ensures proper Z ordering for polygons
49 * outside of valid depth range (otherwise they all have the same depth). It can be useful to disable if you are
50 * performing stencil operations that count on objects having a front and a back (like stencil shadow) and don't
51 * want to clip the back.
52 */
53 bool depthClipEnable = true;
54
55 /**
56 * Scissor rectangle allows you to cull all pixels outside of the scissor rectangle.
57 *
58 * @see ct::RenderAPI::setScissorRect
59 */
60 bool scissorEnable = false;
61
62 /**
63 * Determines how are samples in multi-sample render targets handled. If disabled all samples in the render target
64 * will be written the same value, and if enabled each sample will be generated separately.
65 *
66 * @note In order to get an antialiased image you need to both enable this option and use a MSAA render target.
67 */
68 bool multisampleEnable = true;
69
70 /**
71 * Determines should the lines be antialiased. This is separate from multi-sample antialiasing setting as lines can
72 * be antialiased without multi-sampling.
73 *
74 * @note This setting is usually ignored if MSAA is used, as that provides sufficient antialiasing.
75 */
76 bool antialiasedLineEnable = false;
77 };
78
79 /** Properties of RasterizerState. Shared between sim and core thread versions of RasterizerState. */
80 class BS_CORE_EXPORT RasterizerProperties
81 {
82 public:
83 RasterizerProperties(const RASTERIZER_STATE_DESC& desc);
84
85 /** @copydoc RASTERIZER_STATE_DESC::polygonMode */
86 PolygonMode getPolygonMode() const { return mData.polygonMode; }
87
88 /** @copydoc RASTERIZER_STATE_DESC::cullMode */
89 CullingMode getCullMode() const { return mData.cullMode; }
90
91 /** @copydoc RASTERIZER_STATE_DESC::depthBias */
92 float getDepthBias() const { return mData.depthBias; }
93
94 /** @copydoc RASTERIZER_STATE_DESC::depthBiasClamp */
95 float getDepthBiasClamp() const { return mData.depthBiasClamp; }
96
97 /** @copydoc RASTERIZER_STATE_DESC::slopeScaledDepthBias */
98 float getSlopeScaledDepthBias() const { return mData.slopeScaledDepthBias; }
99
100 /** @copydoc RASTERIZER_STATE_DESC::depthClipEnable */
101 bool getDepthClipEnable() const { return mData.depthClipEnable; }
102
103 /** @copydoc RASTERIZER_STATE_DESC::scissorEnable */
104 bool getScissorEnable() const { return mData.scissorEnable; }
105
106 /** @copydoc RASTERIZER_STATE_DESC::multisampleEnable */
107 bool getMultisampleEnable() const { return mData.multisampleEnable; }
108
109 /** @copydoc RASTERIZER_STATE_DESC::antialiasedLineEnable */
110 bool getAntialiasedLineEnable() const { return mData.antialiasedLineEnable; }
111
112 /** Returns the hash value generated from the rasterizer state properties. */
113 UINT64 getHash() const { return mHash; }
114
115 protected:
116 friend class RasterizerState;
117 friend class ct::RasterizerState;
118 friend class RasterizerStateRTTI;
119
120 RASTERIZER_STATE_DESC mData;
121 UINT64 mHash;
122 };
123
124 /**
125 * Render system pipeline state that allows you to modify how an object is rasterized (how are polygons converted
126 * to pixels).
127 *
128 * @note Rasterizer states are immutable. Sim thread only.
129 */
130 class BS_CORE_EXPORT RasterizerState : public IReflectable, public CoreObject
131 {
132 public:
133 virtual ~RasterizerState();
134
135 /** Returns information about the rasterizer state. */
136 const RasterizerProperties& getProperties() const;
137
138 /** Retrieves a core implementation of the rasterizer state usable only from the core thread. */
139 SPtr<ct::RasterizerState> getCore() const;
140
141 /** Creates a new rasterizer state using the specified rasterizer state descriptor structure. */
142 static SPtr<RasterizerState> create(const RASTERIZER_STATE_DESC& desc);
143
144 /** Returns the default rasterizer state. */
145 static const SPtr<RasterizerState>& getDefault();
146
147 /** Generates a hash value from a rasterizer state descriptor. */
148 static UINT64 generateHash(const RASTERIZER_STATE_DESC& desc);
149
150 protected:
151 friend class RenderStateManager;
152
153 RasterizerState(const RASTERIZER_STATE_DESC& desc);
154
155 /** @copydoc CoreObject::createCore */
156 SPtr<ct::CoreObject> createCore() const override;
157
158 RasterizerProperties mProperties;
159 mutable UINT32 mId;
160
161 /************************************************************************/
162 /* RTTI */
163 /************************************************************************/
164
165 public:
166 friend class RasterizerStateRTTI;
167 static RTTITypeBase* getRTTIStatic();
168 RTTITypeBase* getRTTI() const override;
169 };
170
171 /** @} */
172
173 namespace ct
174 {
175 /** @addtogroup RenderAPI-Internal
176 * @{
177 */
178
179 /**
180 * Core thread version of bs::RasterizerState.
181 *
182 * @note Core thread.
183 */
184 class BS_CORE_EXPORT RasterizerState : public CoreObject
185 {
186 public:
187 virtual ~RasterizerState();
188
189 /** Returns information about the rasterizer state. */
190 const RasterizerProperties& getProperties() const;
191
192 /** Returns a unique state ID. Only the lowest 10 bits are used. */
193 UINT32 getId() const { return mId; }
194
195 /** Creates a new rasterizer state using the specified rasterizer state descriptor structure. */
196 static SPtr<RasterizerState> create(const RASTERIZER_STATE_DESC& desc);
197
198 /** Returns the default rasterizer state. */
199 static const SPtr<RasterizerState>& getDefault();
200
201 protected:
202 friend class RenderStateManager;
203
204 RasterizerState(const RASTERIZER_STATE_DESC& desc, UINT32 id);
205
206 /** @copydoc CoreObject::initialize */
207 void initialize() override;
208
209 /** Creates any API-specific state objects. */
210 virtual void createInternal() { }
211
212 RasterizerProperties mProperties;
213 UINT32 mId;
214 };
215
216 /** @} */
217 }
218
219 BS_ALLOW_MEMCPY_SERIALIZATION(RASTERIZER_STATE_DESC);
220}
221
222/** @cond STDLIB */
223/** @addtogroup RenderAPI
224 * @{
225 */
226
227namespace std
228{
229/** Hash value generator for RASTERIZER_STATE_DESC. */
230template<>
231struct hash<bs::RASTERIZER_STATE_DESC>
232{
233 size_t operator()(const bs::RASTERIZER_STATE_DESC& value) const
234 {
235 return (size_t)bs::RasterizerState::generateHash(value);
236 }
237};
238}
239
240/** @} */
241/** @endcond */
242