1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22
23 #include "../Precompiled.h"
24
25 #include "../Graphics/Camera.h"
26 #include "../Graphics/Graphics.h"
27 #include "../Graphics/Renderer.h"
28 #include "../Graphics/RenderPath.h"
29 #include "../Graphics/View.h"
30 #include "../Resource/ResourceCache.h"
31 #include "../Resource/XMLFile.h"
32 #include "../Scene/Scene.h"
33
34 #include "../DebugNew.h"
35
36 namespace Urho3D
37 {
38
Viewport(Context * context)39 Viewport::Viewport(Context* context) :
40 Object(context),
41 rect_(IntRect::ZERO),
42 drawDebug_(true)
43 {
44 SetRenderPath((RenderPath*)0);
45 }
46
Viewport(Context * context,Scene * scene,Camera * camera,RenderPath * renderPath)47 Viewport::Viewport(Context* context, Scene* scene, Camera* camera, RenderPath* renderPath) :
48 Object(context),
49 scene_(scene),
50 camera_(camera),
51 rect_(IntRect::ZERO),
52 drawDebug_(true)
53 {
54 SetRenderPath(renderPath);
55 }
56
Viewport(Context * context,Scene * scene,Camera * camera,const IntRect & rect,RenderPath * renderPath)57 Viewport::Viewport(Context* context, Scene* scene, Camera* camera, const IntRect& rect, RenderPath* renderPath) :
58 Object(context),
59 scene_(scene),
60 camera_(camera),
61 rect_(rect),
62 drawDebug_(true)
63 {
64 SetRenderPath(renderPath);
65 }
66
~Viewport()67 Viewport::~Viewport()
68 {
69 }
70
SetScene(Scene * scene)71 void Viewport::SetScene(Scene* scene)
72 {
73 scene_ = scene;
74 }
75
SetCamera(Camera * camera)76 void Viewport::SetCamera(Camera* camera)
77 {
78 camera_ = camera;
79 }
80
SetCullCamera(Camera * camera)81 void Viewport::SetCullCamera(Camera* camera)
82 {
83 cullCamera_ = camera;
84 }
85
SetRect(const IntRect & rect)86 void Viewport::SetRect(const IntRect& rect)
87 {
88 rect_ = rect;
89 }
90
SetDrawDebug(bool enable)91 void Viewport::SetDrawDebug(bool enable)
92 {
93 drawDebug_ = enable;
94 }
95
SetRenderPath(RenderPath * renderPath)96 void Viewport::SetRenderPath(RenderPath* renderPath)
97 {
98 if (renderPath)
99 renderPath_ = renderPath;
100 else
101 {
102 Renderer* renderer = GetSubsystem<Renderer>();
103 if (renderer)
104 renderPath_ = renderer->GetDefaultRenderPath();
105 }
106 }
107
SetRenderPath(XMLFile * file)108 void Viewport::SetRenderPath(XMLFile* file)
109 {
110 SharedPtr<RenderPath> newRenderPath(new RenderPath());
111 if (newRenderPath->Load(file))
112 renderPath_ = newRenderPath;
113 }
114
GetScene() const115 Scene* Viewport::GetScene() const
116 {
117 return scene_;
118 }
119
GetCamera() const120 Camera* Viewport::GetCamera() const
121 {
122 return camera_;
123 }
124
GetCullCamera() const125 Camera* Viewport::GetCullCamera() const
126 {
127 return cullCamera_;
128 }
129
GetView() const130 View* Viewport::GetView() const
131 {
132 return view_;
133 }
134
GetRenderPath() const135 RenderPath* Viewport::GetRenderPath() const
136 {
137 return renderPath_;
138 }
139
GetScreenRay(int x,int y) const140 Ray Viewport::GetScreenRay(int x, int y) const
141 {
142 if (!camera_)
143 return Ray();
144
145 float screenX;
146 float screenY;
147
148 if (rect_ == IntRect::ZERO)
149 {
150 Graphics* graphics = GetSubsystem<Graphics>();
151 screenX = (float)x / (float)graphics->GetWidth();
152 screenY = (float)y / (float)graphics->GetHeight();
153 }
154 else
155 {
156 screenX = float(x - rect_.left_) / (float)rect_.Width();
157 screenY = float(y - rect_.top_) / (float)rect_.Height();
158 }
159
160 return camera_->GetScreenRay(screenX, screenY);
161 }
162
WorldToScreenPoint(const Vector3 & worldPos) const163 IntVector2 Viewport::WorldToScreenPoint(const Vector3& worldPos) const
164 {
165 if (!camera_)
166 return IntVector2::ZERO;
167
168 Vector2 screenPoint = camera_->WorldToScreenPoint(worldPos);
169
170 int x;
171 int y;
172 if (rect_ == IntRect::ZERO)
173 {
174 /// \todo This is incorrect if the viewport is used on a texture rendertarget instead of the backbuffer, as it may have different dimensions.
175 Graphics* graphics = GetSubsystem<Graphics>();
176 x = (int)(screenPoint.x_ * graphics->GetWidth());
177 y = (int)(screenPoint.y_ * graphics->GetHeight());
178 }
179 else
180 {
181 x = (int)(rect_.left_ + screenPoint.x_ * rect_.Width());
182 y = (int)(rect_.top_ + screenPoint.y_ * rect_.Height());
183 }
184
185 return IntVector2(x, y);
186 }
187
ScreenToWorldPoint(int x,int y,float depth) const188 Vector3 Viewport::ScreenToWorldPoint(int x, int y, float depth) const
189 {
190 if (!camera_)
191 return Vector3::ZERO;
192
193 float screenX;
194 float screenY;
195
196 if (rect_ == IntRect::ZERO)
197 {
198 /// \todo This is incorrect if the viewport is used on a texture rendertarget instead of the backbuffer, as it may have different dimensions.
199 Graphics* graphics = GetSubsystem<Graphics>();
200 screenX = (float)x / (float)graphics->GetWidth();
201 screenY = (float)y / (float)graphics->GetHeight();
202 }
203 else
204 {
205 screenX = float(x - rect_.left_) / (float)rect_.Width();
206 screenY = float(y - rect_.top_) / (float)rect_.Height();
207 }
208
209 return camera_->ScreenToWorldPoint(Vector3(screenX, screenY, depth));
210 }
211
AllocateView()212 void Viewport::AllocateView()
213 {
214 view_ = new View(context_);
215 }
216
217 }
218