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