Viewport.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #include "../Precompiled.h"
  4. #include "../Graphics/Camera.h"
  5. #include "../Graphics/Graphics.h"
  6. #include "../Graphics/Renderer.h"
  7. #include "../Graphics/RenderPath.h"
  8. #include "../Graphics/View.h"
  9. #include "../Resource/ResourceCache.h"
  10. #include "../Resource/XMLFile.h"
  11. #include "../Scene/Scene.h"
  12. #include "../DebugNew.h"
  13. namespace Urho3D
  14. {
  15. Viewport::Viewport(Context* context) :
  16. Object(context),
  17. rect_(IntRect::ZERO),
  18. drawDebug_(true)
  19. {
  20. SetRenderPath((RenderPath*)nullptr);
  21. }
  22. Viewport::Viewport(Context* context, Scene* scene, Camera* camera, RenderPath* renderPath) :
  23. Object(context),
  24. scene_(scene),
  25. camera_(camera),
  26. rect_(IntRect::ZERO),
  27. drawDebug_(true)
  28. {
  29. SetRenderPath(renderPath);
  30. }
  31. Viewport::Viewport(Context* context, Scene* scene, Camera* camera, const IntRect& rect, RenderPath* renderPath) : // NOLINT(modernize-pass-by-value)
  32. Object(context),
  33. scene_(scene),
  34. camera_(camera),
  35. rect_(rect),
  36. drawDebug_(true)
  37. {
  38. SetRenderPath(renderPath);
  39. }
  40. Viewport::~Viewport() = default;
  41. void Viewport::SetScene(Scene* scene)
  42. {
  43. scene_ = scene;
  44. }
  45. void Viewport::SetCamera(Camera* camera)
  46. {
  47. camera_ = camera;
  48. }
  49. void Viewport::SetCullCamera(Camera* camera)
  50. {
  51. cullCamera_ = camera;
  52. }
  53. void Viewport::SetRect(const IntRect& rect)
  54. {
  55. rect_ = rect;
  56. }
  57. void Viewport::SetDrawDebug(bool enable)
  58. {
  59. drawDebug_ = enable;
  60. }
  61. void Viewport::SetRenderPath(RenderPath* renderPath)
  62. {
  63. if (renderPath)
  64. renderPath_ = renderPath;
  65. else
  66. {
  67. auto* renderer = GetSubsystem<Renderer>();
  68. if (renderer)
  69. renderPath_ = renderer->GetDefaultRenderPath();
  70. }
  71. }
  72. bool Viewport::SetRenderPath(XMLFile* file)
  73. {
  74. SharedPtr<RenderPath> newRenderPath(new RenderPath());
  75. if (newRenderPath->Load(file))
  76. {
  77. renderPath_ = newRenderPath;
  78. return true;
  79. }
  80. return false;
  81. }
  82. Scene* Viewport::GetScene() const
  83. {
  84. return scene_;
  85. }
  86. Camera* Viewport::GetCamera() const
  87. {
  88. return camera_;
  89. }
  90. Camera* Viewport::GetCullCamera() const
  91. {
  92. return cullCamera_;
  93. }
  94. View* Viewport::GetView() const
  95. {
  96. return view_;
  97. }
  98. RenderPath* Viewport::GetRenderPath() const
  99. {
  100. return renderPath_;
  101. }
  102. Ray Viewport::GetScreenRay(int x, int y) const
  103. {
  104. if (!camera_)
  105. return Ray();
  106. float screenX;
  107. float screenY;
  108. if (rect_ == IntRect::ZERO)
  109. {
  110. auto* graphics = GetSubsystem<Graphics>();
  111. screenX = (float)x / (float)graphics->GetWidth();
  112. screenY = (float)y / (float)graphics->GetHeight();
  113. }
  114. else
  115. {
  116. screenX = float(x - rect_.left_) / (float)rect_.Width();
  117. screenY = float(y - rect_.top_) / (float)rect_.Height();
  118. }
  119. return camera_->GetScreenRay(screenX, screenY);
  120. }
  121. IntVector2 Viewport::WorldToScreenPoint(const Vector3& worldPos) const
  122. {
  123. if (!camera_)
  124. return IntVector2::ZERO;
  125. Vector2 screenPoint = camera_->WorldToScreenPoint(worldPos);
  126. int x;
  127. int y;
  128. if (rect_ == IntRect::ZERO)
  129. {
  130. /// \todo This is incorrect if the viewport is used on a texture rendertarget instead of the backbuffer, as it may have different dimensions.
  131. auto* graphics = GetSubsystem<Graphics>();
  132. x = (int)(screenPoint.x_ * graphics->GetWidth());
  133. y = (int)(screenPoint.y_ * graphics->GetHeight());
  134. }
  135. else
  136. {
  137. x = (int)(rect_.left_ + screenPoint.x_ * rect_.Width());
  138. y = (int)(rect_.top_ + screenPoint.y_ * rect_.Height());
  139. }
  140. return IntVector2(x, y);
  141. }
  142. Vector3 Viewport::ScreenToWorldPoint(int x, int y, float depth) const
  143. {
  144. if (!camera_)
  145. return Vector3::ZERO;
  146. float screenX;
  147. float screenY;
  148. if (rect_ == IntRect::ZERO)
  149. {
  150. /// \todo This is incorrect if the viewport is used on a texture rendertarget instead of the backbuffer, as it may have different dimensions.
  151. auto* graphics = GetSubsystem<Graphics>();
  152. screenX = (float)x / (float)graphics->GetWidth();
  153. screenY = (float)y / (float)graphics->GetHeight();
  154. }
  155. else
  156. {
  157. screenX = float(x - rect_.left_) / (float)rect_.Width();
  158. screenY = float(y - rect_.top_) / (float)rect_.Height();
  159. }
  160. return camera_->ScreenToWorldPoint(Vector3(screenX, screenY, depth));
  161. }
  162. void Viewport::AllocateView()
  163. {
  164. view_ = new View(context_);
  165. }
  166. }