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#include "RenderAPI/BsViewport.h"
4#include "Private/RTTI/BsViewportRTTI.h"
5#include "Error/BsException.h"
6#include "RenderAPI/BsRenderTarget.h"
7#include "Math/BsMath.h"
8#include "RenderAPI/BsRenderAPI.h"
9#include "CoreThread/BsCoreObjectSync.h"
10
11namespace bs
12{
13 const Color ViewportBase::DEFAULT_CLEAR_COLOR = Color(0.0f, 0.3685f, 0.7969f);
14
15 ViewportBase::ViewportBase(float x, float y, float width, float height)
16 : mNormArea(x, y, width, height), mClearFlags(ClearFlagBits::Color | ClearFlagBits::Depth)
17 , mClearColorValue(DEFAULT_CLEAR_COLOR), mClearDepthValue(1.0f), mClearStencilValue(0)
18 {
19
20 }
21
22 void ViewportBase::setArea(const Rect2& area)
23 {
24 mNormArea = area;
25
26 _markCoreDirty();
27 }
28
29 Rect2I ViewportBase::getPixelArea() const
30 {
31 float width = (float)getTargetWidth();
32 float height = (float)getTargetHeight();
33
34 Rect2I area;
35 area.x = (int)(mNormArea.x * width);
36 area.y = (int)(mNormArea.y * height);
37 area.width = (int)(mNormArea.width * width);
38 area.height = (int)(mNormArea.height * height);
39
40 return area;
41 }
42
43 void ViewportBase::setClearFlags(ClearFlags flags)
44 {
45 mClearFlags = flags;
46
47 _markCoreDirty();
48 }
49
50 void ViewportBase::setClearValues(const Color& clearColor, float clearDepth, UINT16 clearStencil)
51 {
52 mClearColorValue = clearColor;
53 mClearDepthValue = clearDepth;
54 mClearStencilValue = clearStencil;
55
56 _markCoreDirty();
57 }
58
59 void ViewportBase::setClearColorValue(const Color& color)
60 {
61 mClearColorValue = color;
62
63 _markCoreDirty();
64 }
65
66 void ViewportBase::setClearDepthValue(float depth)
67 {
68 mClearDepthValue = depth;
69
70 _markCoreDirty();
71 }
72
73 void ViewportBase::setClearStencilValue(UINT16 value)
74 {
75 mClearStencilValue = value;
76
77 _markCoreDirty();
78 }
79
80 template <bool Core>
81 template <class P>
82 void TViewport<Core>::rttiEnumFields(P p)
83 {
84 p(mNormArea);
85 p(mClearFlags);
86 p(mClearColorValue);
87 p(mClearDepthValue);
88 p(mClearStencilValue);
89 p(mTarget);
90 }
91
92 Viewport::Viewport(const SPtr<RenderTarget>& target, float x, float y, float width, float height)
93 :TViewport(target, x, y, width, height)
94 {
95 }
96
97 void Viewport::setTarget(const SPtr<RenderTarget>& target)
98 {
99 mTarget = target;
100
101 markDependenciesDirty();
102 _markCoreDirty();
103 }
104
105 SPtr<ct::Viewport> Viewport::getCore() const
106 {
107 return std::static_pointer_cast<ct::Viewport>(mCoreSpecific);
108 }
109
110 void Viewport::_markCoreDirty()
111 {
112 markCoreDirty();
113 }
114
115 UINT32 Viewport::getTargetWidth() const
116 {
117 if (mTarget != nullptr)
118 return mTarget->getProperties().width;
119
120 return 0;
121 }
122
123 UINT32 Viewport::getTargetHeight() const
124 {
125 if(mTarget != nullptr)
126 return mTarget->getProperties().height;
127
128 return 0;
129 }
130
131 SPtr<ct::CoreObject> Viewport::createCore() const
132 {
133 SPtr<ct::RenderTarget> targetCore;
134 if (mTarget != nullptr)
135 targetCore = mTarget->getCore();
136
137 ct::Viewport* viewport = new (bs_alloc<ct::Viewport>())
138 ct::Viewport(targetCore, mNormArea.x, mNormArea.y, mNormArea.width, mNormArea.height);
139
140 SPtr<ct::Viewport> viewportPtr = bs_shared_ptr<ct::Viewport>(viewport);
141 viewportPtr->_setThisPtr(viewportPtr);
142
143 return viewportPtr;
144 }
145
146 CoreSyncData Viewport::syncToCore(FrameAlloc* allocator)
147 {
148 UINT32 size = coreSyncGetElemSize(*this);
149
150 UINT8* buffer = allocator->alloc(size);
151
152 char* dataPtr = (char*)buffer;
153 dataPtr = coreSyncWriteElem(*this, dataPtr);
154
155 return CoreSyncData(buffer, size);
156 }
157
158 void Viewport::getCoreDependencies(Vector<CoreObject*>& dependencies)
159 {
160 if (mTarget != nullptr)
161 dependencies.push_back(mTarget.get());
162 }
163
164 SPtr<Viewport> Viewport::create(const SPtr<RenderTarget>& target, float x, float y, float width, float height)
165 {
166 Viewport* viewport = new (bs_alloc<Viewport>()) Viewport(target, x, y, width, height);
167 SPtr<Viewport> viewportPtr = bs_core_ptr<Viewport>(viewport);
168 viewportPtr->_setThisPtr(viewportPtr);
169 viewportPtr->initialize();
170
171 return viewportPtr;
172 }
173
174 SPtr<Viewport> Viewport::createEmpty()
175 {
176 Viewport* viewport = new (bs_alloc<Viewport>()) Viewport();
177 SPtr<Viewport> viewportPtr = bs_core_ptr<Viewport>(viewport);
178 viewportPtr->_setThisPtr(viewportPtr);
179
180 return viewportPtr;
181 }
182
183 RTTITypeBase* Viewport::getRTTIStatic()
184 {
185 return ViewportRTTI::instance();
186 }
187
188 RTTITypeBase* Viewport::getRTTI() const
189 {
190 return Viewport::getRTTIStatic();
191 }
192
193 namespace ct
194 {
195 Viewport::Viewport(const SPtr<RenderTarget>& target, float x, float y, float width, float height)
196 :TViewport(target, x, y, width, height)
197 { }
198
199 SPtr<Viewport> Viewport::create(const SPtr<RenderTarget>& target, float x, float y, float width, float height)
200 {
201 Viewport* viewport = new (bs_alloc<Viewport>()) Viewport(target, x, y, width, height);
202
203 SPtr<Viewport> viewportPtr = bs_shared_ptr<Viewport>(viewport);
204 viewportPtr->_setThisPtr(viewportPtr);
205 viewportPtr->initialize();
206
207 return viewportPtr;
208 }
209
210 UINT32 Viewport::getTargetWidth() const
211 {
212 if (mTarget != nullptr)
213 return mTarget->getProperties().width;
214
215 return 0;
216 }
217
218 UINT32 Viewport::getTargetHeight() const
219 {
220 if (mTarget != nullptr)
221 return mTarget->getProperties().height;
222
223 return 0;
224 }
225
226 void Viewport::syncToCore(const CoreSyncData& data)
227 {
228 char* dataPtr = (char*)data.getBuffer();
229 coreSyncReadElem(*this, dataPtr);
230 }
231 }
232}
233