BsHandleDrawManager.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #include "BsHandleDrawManager.h"
  2. #include "BsDrawHelper.h"
  3. #include "BsMaterial.h"
  4. #include "BsBuiltinEditorResources.h"
  5. #include "BsCoreThread.h"
  6. #include "BsRendererManager.h"
  7. #include "BsRenderer.h"
  8. #include "BsTransientMesh.h"
  9. #include "BsCamera.h"
  10. #include "BsSceneObject.h"
  11. using namespace std::placeholders;
  12. namespace BansheeEngine
  13. {
  14. const UINT32 HandleDrawManager::SPHERE_QUALITY = 1;
  15. const UINT32 HandleDrawManager::WIRE_SPHERE_QUALITY = 10;
  16. const UINT32 HandleDrawManager::ARC_QUALITY = 10;
  17. HandleDrawManager::HandleDrawManager()
  18. :mCore(nullptr)
  19. {
  20. mDrawHelper = bs_new<DrawHelper>();
  21. HMaterial solidMaterial = BuiltinEditorResources::instance().createSolidHandleMat();
  22. HMaterial wireMaterial = BuiltinEditorResources::instance().createWireHandleMat();
  23. MaterialProxyPtr solidMaterialProxy = solidMaterial->_createProxy();
  24. MaterialProxyPtr wireMaterialProxy = wireMaterial->_createProxy();
  25. mCore = bs_new<HandleDrawManagerCore>(HandleDrawManagerCore::PrivatelyConstruct());
  26. gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::initializeCore, this, wireMaterialProxy, solidMaterialProxy));
  27. }
  28. HandleDrawManager::~HandleDrawManager()
  29. {
  30. bs_delete(mDrawHelper);
  31. gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::destroyCore, this, mCore));
  32. }
  33. void HandleDrawManager::initializeCore(const MaterialProxyPtr& wireMatProxy, const MaterialProxyPtr& solidMatProxy)
  34. {
  35. THROW_IF_NOT_CORE_THREAD;
  36. mCore->initialize(wireMatProxy, solidMatProxy);
  37. }
  38. void HandleDrawManager::destroyCore(HandleDrawManagerCore* core)
  39. {
  40. THROW_IF_NOT_CORE_THREAD;
  41. bs_delete(core);
  42. }
  43. void HandleDrawManager::setColor(const Color& color)
  44. {
  45. mDrawHelper->setColor(color);
  46. }
  47. void HandleDrawManager::setTransform(const Matrix4& transform)
  48. {
  49. mDrawHelper->setTransform(transform);
  50. }
  51. void HandleDrawManager::drawCube(const Vector3& position, const Vector3& extents)
  52. {
  53. mDrawHelper->cube(position, extents);
  54. }
  55. void HandleDrawManager::drawSphere(const Vector3& position, float radius)
  56. {
  57. mDrawHelper->sphere(position, radius);
  58. }
  59. void HandleDrawManager::drawWireCube(const Vector3& position, const Vector3& extents)
  60. {
  61. mDrawHelper->wireCube(position, extents);
  62. }
  63. void HandleDrawManager::drawWireSphere(const Vector3& position, float radius)
  64. {
  65. mDrawHelper->wireSphere(position, radius);
  66. }
  67. void HandleDrawManager::drawCone(const Vector3& base, const Vector3& normal, float height, float radius)
  68. {
  69. mDrawHelper->cone(base, normal, height, radius);
  70. }
  71. void HandleDrawManager::drawLine(const Vector3& start, const Vector3& end)
  72. {
  73. mDrawHelper->line(start, end);
  74. }
  75. void HandleDrawManager::drawDisc(const Vector3& position, const Vector3& normal, float radius)
  76. {
  77. mDrawHelper->disc(position, normal, radius);
  78. }
  79. void HandleDrawManager::drawWireDisc(const Vector3& position, const Vector3& normal, float radius)
  80. {
  81. mDrawHelper->wireDisc(position, normal, radius);
  82. }
  83. void HandleDrawManager::drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle)
  84. {
  85. mDrawHelper->arc(position, normal, radius, startAngle, amountAngle);
  86. }
  87. void HandleDrawManager::drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle)
  88. {
  89. mDrawHelper->wireArc(position, normal, radius, startAngle, amountAngle);
  90. }
  91. void HandleDrawManager::drawRect(const Rect3& area)
  92. {
  93. mDrawHelper->rectangle(area);
  94. }
  95. void HandleDrawManager::draw(const HCamera& camera)
  96. {
  97. mDrawHelper->clearMeshes();
  98. mDrawHelper->buildMeshes(DrawHelper::SortType::BackToFront, camera->SO()->getWorldPosition());
  99. const Vector<DrawHelper::ShapeMeshData>& meshes = mDrawHelper->getMeshes();
  100. Vector<HandleDrawManagerCore::MeshProxyData> proxyData;
  101. for (auto& meshData : meshes)
  102. {
  103. if (meshData.type == DrawHelper::MeshType::Solid)
  104. {
  105. MeshProxyPtr proxy = meshData.mesh->_createProxy(0);
  106. proxyData.push_back(HandleDrawManagerCore::MeshProxyData(proxy, HandleDrawManagerCore::MeshType::Solid));
  107. }
  108. else // Wire
  109. {
  110. MeshProxyPtr proxy = meshData.mesh->_createProxy(0);
  111. proxyData.push_back(HandleDrawManagerCore::MeshProxyData(proxy, HandleDrawManagerCore::MeshType::Wire));
  112. }
  113. }
  114. RenderTargetPtr sceneRenderTarget = camera->getViewport()->getTarget();
  115. gCoreAccessor().queueCommand(std::bind(&HandleDrawManagerCore::updateData, mCore,
  116. sceneRenderTarget, proxyData));
  117. mDrawHelper->clear();
  118. }
  119. void HandleDrawManagerCore::initialize(const MaterialProxyPtr& wireMatProxy, const MaterialProxyPtr& solidMatProxy)
  120. {
  121. // TODO - Make a better interface when dealing with parameters through proxies?
  122. {
  123. mWireMaterial.proxy = wireMatProxy;
  124. GpuParamsPtr vertParams = wireMatProxy->params[wireMatProxy->passes[0].vertexProgParamsIdx];
  125. vertParams->getParam("matViewProj", mWireMaterial.mViewProj);
  126. }
  127. {
  128. mSolidMaterial.proxy = solidMatProxy;
  129. GpuParamsPtr vertParams = solidMatProxy->params[solidMatProxy->passes[0].vertexProgParamsIdx];
  130. vertParams->getParam("matViewProj", mSolidMaterial.mViewProj);
  131. }
  132. RendererPtr activeRenderer = RendererManager::instance().getActive();
  133. activeRenderer->onCorePostRenderViewport.connect(std::bind(&HandleDrawManagerCore::render, this, _1));
  134. }
  135. void HandleDrawManagerCore::updateData(const RenderTargetPtr& rt, const Vector<MeshProxyData>& proxies)
  136. {
  137. mSceneRenderTarget = rt;
  138. mProxies = proxies;
  139. }
  140. void HandleDrawManagerCore::render(const CameraProxy& camera)
  141. {
  142. THROW_IF_NOT_CORE_THREAD;
  143. if (camera.viewport.getTarget() != mSceneRenderTarget)
  144. return;
  145. float width = (float)mSceneRenderTarget->getCore()->getProperties().getWidth();
  146. float height = (float)mSceneRenderTarget->getCore()->getProperties().getHeight();
  147. Rect2 normArea = camera.viewport.getNormArea();
  148. Rect2I screenArea;
  149. screenArea.x = (int)(normArea.x * width);
  150. screenArea.y = (int)(normArea.y * height);
  151. screenArea.width = (int)(normArea.width * width);
  152. screenArea.height = (int)(normArea.height * height);
  153. Matrix4 viewProjMat = camera.projMatrix * camera.viewMatrix;
  154. mSolidMaterial.mViewProj.set(viewProjMat);
  155. mWireMaterial.mViewProj.set(viewProjMat);
  156. MeshType currentType = MeshType::Solid;
  157. if (mProxies.size() > 0)
  158. {
  159. currentType = mProxies[0].type;
  160. if (currentType == MeshType::Solid)
  161. Renderer::setPass(*mSolidMaterial.proxy, 0);
  162. else
  163. Renderer::setPass(*mWireMaterial.proxy, 0);
  164. }
  165. for (auto& proxyData : mProxies)
  166. {
  167. if (currentType != proxyData.type)
  168. {
  169. if (currentType == MeshType::Solid)
  170. Renderer::setPass(*mSolidMaterial.proxy, 0);
  171. else
  172. Renderer::setPass(*mWireMaterial.proxy, 0);
  173. currentType = proxyData.type;
  174. }
  175. Renderer::draw(*proxyData.proxy);
  176. }
  177. }
  178. }