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 <utility> |
6 | #include "BsCorePrerequisites.h" |
7 | #include "Reflection/BsIReflectable.h" |
8 | #include "CoreThread/BsCoreObject.h" |
9 | #include "Image/BsColor.h" |
10 | #include "Math/BsRect2I.h" |
11 | #include "Math/BsRect2.h" |
12 | #include "Utility/BsEvent.h" |
13 | |
14 | namespace bs |
15 | { |
16 | /** @addtogroup Implementation |
17 | * @{ |
18 | */ |
19 | |
20 | /** Flags that determine which portion of the viewport to clear. */ |
21 | enum BS_SCRIPT_EXPORT(n:ClearFlags) class ClearFlagBits |
22 | { |
23 | Empty, |
24 | Color = 1 << 0, |
25 | Depth = 1 << 1, |
26 | Stencil = 1 << 2 |
27 | }; |
28 | |
29 | typedef Flags<ClearFlagBits> ClearFlags; |
30 | BS_FLAGS_OPERATORS(ClearFlagBits) |
31 | |
32 | /** Common base type used for both sim and core thread variants of Viewport. */ |
33 | class BS_CORE_EXPORT ViewportBase |
34 | { |
35 | public: |
36 | virtual ~ViewportBase() = default; |
37 | |
38 | /** Determines the area that the viewport covers. Coordinates are in normalized [0, 1] range. */ |
39 | BS_SCRIPT_EXPORT(n:Area,pr:setter) |
40 | void setArea(const Rect2& area); |
41 | |
42 | /** @copydoc setArea() */ |
43 | BS_SCRIPT_EXPORT(n:Area,pr:getter) |
44 | Rect2 getArea() const { return mNormArea; } |
45 | |
46 | /** Returns the area of the render target covered by the viewport, in pixels. */ |
47 | BS_SCRIPT_EXPORT(n:PixelArea,pr:getter) |
48 | Rect2I getPixelArea() const; |
49 | |
50 | /** Determines which portions of the render target should be cleared before rendering to this viewport is performed. */ |
51 | BS_SCRIPT_EXPORT(n:ClearFlags,pr:setter) |
52 | void setClearFlags(ClearFlags flags); |
53 | |
54 | /** @copydoc setClearFlags() */ |
55 | BS_SCRIPT_EXPORT(n:ClearFlags,pr:getter) |
56 | ClearFlags getClearFlags() const { return mClearFlags; } |
57 | |
58 | /** Sets values to clear color, depth and stencil buffers to. */ |
59 | void setClearValues(const Color& clearColor, float clearDepth = 0.0f, UINT16 clearStencil = 0); |
60 | |
61 | /** Determines the color to clear the viewport to before rendering, if color clear is enabled. */ |
62 | BS_SCRIPT_EXPORT(n:ClearColor,pr:setter) |
63 | void setClearColorValue(const Color& color); |
64 | |
65 | /** @copydoc setClearColorValue() */ |
66 | BS_SCRIPT_EXPORT(n:ClearColor,pr:getter) |
67 | const Color& getClearColorValue() const { return mClearColorValue; } |
68 | |
69 | /** Determines the value to clear the depth buffer to before rendering, if depth clear is enabled. */ |
70 | BS_SCRIPT_EXPORT(n:ClearDepth,pr:setter) |
71 | void setClearDepthValue(float depth); |
72 | |
73 | /** @copydoc setClearDepthValue() */ |
74 | BS_SCRIPT_EXPORT(n:ClearDepth,pr:getter) |
75 | float getClearDepthValue() const { return mClearDepthValue; } |
76 | |
77 | /** Determines the value to clear the stencil buffer to before rendering, if stencil clear is enabled. */ |
78 | BS_SCRIPT_EXPORT(n:ClearStencil,pr:setter) |
79 | void setClearStencilValue(UINT16 value); |
80 | |
81 | /** @copydoc setClearStencilValue() */ |
82 | BS_SCRIPT_EXPORT(n:ClearStencil,pr:getter) |
83 | UINT16 getClearStencilValue() const { return mClearStencilValue; } |
84 | |
85 | protected: |
86 | ViewportBase(float x = 0.0f, float y = 0.0f, float width = 1.0f, float height = 1.0f); |
87 | |
88 | /** |
89 | * Marks the core data as dirty. This causes the data from the sim thread object be synced with the core thread |
90 | * version of the object. |
91 | */ |
92 | virtual void _markCoreDirty() { } |
93 | |
94 | /** Gets the render target width. */ |
95 | virtual UINT32 getTargetWidth() const = 0; |
96 | |
97 | /** Gets the render target width. */ |
98 | virtual UINT32 getTargetHeight() const = 0; |
99 | |
100 | Rect2 mNormArea; |
101 | |
102 | ClearFlags mClearFlags; |
103 | Color mClearColorValue; |
104 | float mClearDepthValue; |
105 | UINT16 mClearStencilValue; |
106 | |
107 | static const Color DEFAULT_CLEAR_COLOR; |
108 | }; |
109 | |
110 | /** Templated common base type used for both sim and core thread variants of Viewport. */ |
111 | template<bool Core> |
112 | class TViewport : public ViewportBase |
113 | { |
114 | public: |
115 | using RenderTargetType = CoreVariantType<RenderTarget, Core>; |
116 | |
117 | TViewport(SPtr<RenderTargetType> target = nullptr, float x = 0.0f, float y = 0.0f, float width = 1.0f, |
118 | float height = 1.0f) |
119 | :ViewportBase(x, y, width, height), mTarget(std::move(target)) |
120 | { } |
121 | virtual ~TViewport() = default; |
122 | |
123 | /** Enumerates all the fields in the type and executes the specified processor action for each field. */ |
124 | template<class P> |
125 | void rttiEnumFields(P p); |
126 | |
127 | protected: |
128 | SPtr<RenderTargetType> mTarget; |
129 | }; |
130 | |
131 | /** @} */ |
132 | |
133 | /** @addtogroup RenderAPI |
134 | * @{ |
135 | */ |
136 | |
137 | /** |
138 | * Viewport determines to which RenderTarget should rendering be performed. It allows you to render to a sub-region of the |
139 | * target by specifying the area rectangle, and allows you to set up color/depth/stencil clear values for that specific region. |
140 | */ |
141 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Rendering) Viewport : public IReflectable, public CoreObject, public TViewport<false> |
142 | { |
143 | public: |
144 | /** Determines the render target the viewport is associated with. */ |
145 | BS_SCRIPT_EXPORT(n:Target,pr:setter) |
146 | void setTarget(const SPtr<RenderTarget>& target); |
147 | |
148 | /** @copydoc setTarget() */ |
149 | BS_SCRIPT_EXPORT(n:Target,pr:getter) |
150 | SPtr<RenderTarget> getTarget() const { return mTarget; } |
151 | |
152 | /** Retrieves a core implementation of a viewport usable only from the core thread. */ |
153 | SPtr<ct::Viewport> getCore() const; |
154 | |
155 | /** |
156 | * Creates a new viewport. |
157 | * |
158 | * @note Viewport coordinates are normalized in [0, 1] range. |
159 | */ |
160 | BS_SCRIPT_EXPORT(ec:Viewport) |
161 | static SPtr<Viewport> create(const SPtr<RenderTarget>& target, float x = 0.0f, float y = 0.0f, |
162 | float width = 1.0f, float height = 1.0f); |
163 | |
164 | protected: |
165 | Viewport(const SPtr<RenderTarget>& target, float x = 0.0f, float y = 0.0f, float width = 1.0f, float height = 1.0f); |
166 | |
167 | /** @copydoc ViewportBase::_markCoreDirty */ |
168 | void _markCoreDirty() override; |
169 | |
170 | /** @copydoc ViewportBase::getTargetWidth */ |
171 | UINT32 getTargetWidth() const override; |
172 | |
173 | /** @copydoc ViewportBase::getTargetHeight */ |
174 | UINT32 getTargetHeight() const override; |
175 | |
176 | /** @copydoc CoreObject::syncToCore */ |
177 | CoreSyncData syncToCore(FrameAlloc* allocator) override; |
178 | |
179 | /** @copydoc CoreObject::getCoreDependencies */ |
180 | void getCoreDependencies(Vector<CoreObject*>& dependencies) override; |
181 | |
182 | /** @copydoc CoreObject::createCore */ |
183 | SPtr<ct::CoreObject> createCore() const override; |
184 | |
185 | /************************************************************************/ |
186 | /* RTTI */ |
187 | /************************************************************************/ |
188 | Viewport() = default; |
189 | |
190 | /** Creates an empty viewport for serialization purposes. */ |
191 | static SPtr<Viewport> createEmpty(); |
192 | public: |
193 | friend class ViewportRTTI; |
194 | static RTTITypeBase* getRTTIStatic(); |
195 | RTTITypeBase* getRTTI() const override; |
196 | }; |
197 | |
198 | /** @} */ |
199 | |
200 | namespace ct |
201 | { |
202 | /** @addtogroup RenderAPI-Internal |
203 | * @{ |
204 | */ |
205 | |
206 | /** @copydoc bs::Viewport */ |
207 | class BS_CORE_EXPORT Viewport : public CoreObject, public TViewport<true> |
208 | { |
209 | public: |
210 | /** Returns the render target the viewport is associated with. */ |
211 | SPtr<RenderTarget> getTarget() const { return mTarget; } |
212 | |
213 | /** Sets the render target the viewport will be associated with. */ |
214 | void setTarget(const SPtr<RenderTarget>& target) { mTarget = target; } |
215 | |
216 | /** @copydoc bs::Viewport::create() */ |
217 | static SPtr<Viewport> create(const SPtr<RenderTarget>& target, float x = 0.0f, float y = 0.0f, |
218 | float width = 1.0f, float height = 1.0f); |
219 | |
220 | protected: |
221 | friend class bs::Viewport; |
222 | |
223 | Viewport(const SPtr<RenderTarget>& target, float x = 0.0f, float y = 0.0f, float width = 1.0f, float height = 1.0f); |
224 | |
225 | /** @copydoc ViewportBase::getTargetWidth */ |
226 | UINT32 getTargetWidth() const override; |
227 | |
228 | /** @copydoc ViewportBase::getTargetHeight */ |
229 | UINT32 getTargetHeight() const override; |
230 | |
231 | /** @copydoc CoreObject::syncToCore */ |
232 | void syncToCore(const CoreSyncData& data) override; |
233 | }; |
234 | |
235 | /** @} */ |
236 | } |
237 | } |