BsHandleDrawManager.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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 "BsCameraHandler.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. mTransform = Matrix4::IDENTITY;
  21. mDrawHelper = bs_new<DrawHelper>();
  22. HMaterial solidMaterial = BuiltinEditorResources::instance().createSolidHandleMat();
  23. HMaterial wireMaterial = BuiltinEditorResources::instance().createWireHandleMat();
  24. MaterialProxyPtr solidMaterialProxy = solidMaterial->_createProxy();
  25. MaterialProxyPtr wireMaterialProxy = wireMaterial->_createProxy();
  26. mCore = bs_new<HandleDrawManagerCore>(HandleDrawManagerCore::PrivatelyConstruct());
  27. gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::initializeCore, this, wireMaterialProxy, solidMaterialProxy));
  28. }
  29. HandleDrawManager::~HandleDrawManager()
  30. {
  31. bs_delete(mDrawHelper);
  32. gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::destroyCore, this, mCore));
  33. }
  34. void HandleDrawManager::initializeCore(const MaterialProxyPtr& wireMatProxy, const MaterialProxyPtr& solidMatProxy)
  35. {
  36. THROW_IF_NOT_CORE_THREAD;
  37. mCore->initialize(wireMatProxy, solidMatProxy);
  38. }
  39. void HandleDrawManager::destroyCore(HandleDrawManagerCore* core)
  40. {
  41. THROW_IF_NOT_CORE_THREAD;
  42. bs_delete(core);
  43. }
  44. void HandleDrawManager::setColor(const Color& color)
  45. {
  46. mDrawHelper->setColor(color);
  47. }
  48. void HandleDrawManager::setTransform(const Matrix4& transform)
  49. {
  50. mTransform = transform;
  51. }
  52. void HandleDrawManager::drawCube(const Vector3& position, const Vector3& extents, float size)
  53. {
  54. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  55. mDrawHelper->setTransform(scale * mTransform);
  56. mDrawHelper->cube(position, extents);
  57. }
  58. void HandleDrawManager::drawSphere(const Vector3& position, float radius, float size)
  59. {
  60. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  61. mDrawHelper->setTransform(scale * mTransform);
  62. mDrawHelper->sphere(position, radius);
  63. }
  64. void HandleDrawManager::drawWireCube(const Vector3& position, const Vector3& extents, float size)
  65. {
  66. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  67. mDrawHelper->setTransform(scale * mTransform);
  68. mDrawHelper->wireCube(position, extents);
  69. }
  70. void HandleDrawManager::drawWireSphere(const Vector3& position, float radius, float size)
  71. {
  72. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  73. mDrawHelper->setTransform(scale * mTransform);
  74. mDrawHelper->wireSphere(position, radius);
  75. }
  76. void HandleDrawManager::drawCone(const Vector3& base, const Vector3& normal, float height, float radius, float size)
  77. {
  78. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  79. mDrawHelper->setTransform(scale * mTransform);
  80. mDrawHelper->cone(base, normal, height, radius);
  81. }
  82. void HandleDrawManager::drawLine(const Vector3& start, const Vector3& end, float size)
  83. {
  84. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  85. mDrawHelper->setTransform(scale * mTransform);
  86. mDrawHelper->line(start, end);
  87. }
  88. void HandleDrawManager::drawDisc(const Vector3& position, const Vector3& normal, float radius, float size)
  89. {
  90. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  91. mDrawHelper->setTransform(scale * mTransform);
  92. mDrawHelper->disc(position, normal, radius);
  93. }
  94. void HandleDrawManager::drawWireDisc(const Vector3& position, const Vector3& normal, float radius, float size)
  95. {
  96. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  97. mDrawHelper->setTransform(scale * mTransform);
  98. mDrawHelper->wireDisc(position, normal, radius);
  99. }
  100. void HandleDrawManager::drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size)
  101. {
  102. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  103. mDrawHelper->setTransform(scale * mTransform);
  104. mDrawHelper->arc(position, normal, radius, startAngle, amountAngle);
  105. }
  106. void HandleDrawManager::drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size)
  107. {
  108. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  109. mDrawHelper->setTransform(scale * mTransform);
  110. mDrawHelper->wireArc(position, normal, radius, startAngle, amountAngle);
  111. }
  112. void HandleDrawManager::drawRect(const Rect3& area, float size)
  113. {
  114. Matrix4 scale(Vector3::ZERO, Quaternion::IDENTITY, Vector3(size, size, size));
  115. mDrawHelper->setTransform(scale * mTransform);
  116. mDrawHelper->rectangle(area);
  117. }
  118. void HandleDrawManager::draw(const CameraHandlerPtr& camera)
  119. {
  120. mDrawHelper->clearMeshes();
  121. mDrawHelper->buildMeshes(DrawHelper::SortType::BackToFront, camera->getPosition());
  122. const Vector<DrawHelper::ShapeMeshData>& meshes = mDrawHelper->getMeshes();
  123. Vector<HandleDrawManagerCore::MeshData> proxyData;
  124. for (auto& meshData : meshes)
  125. {
  126. if (meshData.type == DrawHelper::MeshType::Solid)
  127. {
  128. proxyData.push_back(HandleDrawManagerCore::MeshData(
  129. meshData.mesh->getCore(), HandleDrawManagerCore::MeshType::Solid));
  130. }
  131. else // Wire
  132. {
  133. proxyData.push_back(HandleDrawManagerCore::MeshData(
  134. meshData.mesh->getCore(), HandleDrawManagerCore::MeshType::Wire));
  135. }
  136. }
  137. RenderTargetPtr sceneRenderTarget = camera->getViewport()->getTarget();
  138. gCoreAccessor().queueCommand(std::bind(&HandleDrawManagerCore::updateData, mCore,
  139. sceneRenderTarget, proxyData));
  140. mDrawHelper->clear();
  141. }
  142. void HandleDrawManagerCore::initialize(const MaterialProxyPtr& wireMatProxy, const MaterialProxyPtr& solidMatProxy)
  143. {
  144. // TODO - Make a better interface when dealing with parameters through proxies?
  145. {
  146. mWireMaterial.proxy = wireMatProxy;
  147. GpuParamsPtr vertParams = wireMatProxy->params[wireMatProxy->passes[0].vertexProgParamsIdx];
  148. vertParams->getParam("matViewProj", mWireMaterial.mViewProj);
  149. }
  150. {
  151. mSolidMaterial.proxy = solidMatProxy;
  152. GpuParamsPtr vertParams = solidMatProxy->params[solidMatProxy->passes[0].vertexProgParamsIdx];
  153. vertParams->getParam("matViewProj", mSolidMaterial.mViewProj);
  154. }
  155. RendererPtr activeRenderer = RendererManager::instance().getActive();
  156. activeRenderer->onCorePostRenderViewport.connect(std::bind(&HandleDrawManagerCore::render, this, _1));
  157. }
  158. void HandleDrawManagerCore::updateData(const RenderTargetPtr& rt, const Vector<MeshData>& meshes)
  159. {
  160. mSceneRenderTarget = rt;
  161. mMeshes = meshes;
  162. }
  163. void HandleDrawManagerCore::render(const CameraProxy& camera)
  164. {
  165. THROW_IF_NOT_CORE_THREAD;
  166. SPtr<RenderTargetCore> sceneRenderTarget = mSceneRenderTarget->getCore();
  167. if (camera.renderTarget != sceneRenderTarget)
  168. return;
  169. float width = (float)sceneRenderTarget->getProperties().getWidth();
  170. float height = (float)sceneRenderTarget->getProperties().getHeight();
  171. Rect2 normArea = camera.viewport.getNormArea();
  172. Rect2I screenArea;
  173. screenArea.x = (int)(normArea.x * width);
  174. screenArea.y = (int)(normArea.y * height);
  175. screenArea.width = (int)(normArea.width * width);
  176. screenArea.height = (int)(normArea.height * height);
  177. Matrix4 viewProjMat = camera.projMatrix * camera.viewMatrix;
  178. mSolidMaterial.mViewProj.set(viewProjMat);
  179. mWireMaterial.mViewProj.set(viewProjMat);
  180. MeshType currentType = MeshType::Solid;
  181. if (mMeshes.size() > 0)
  182. {
  183. currentType = mMeshes[0].type;
  184. if (currentType == MeshType::Solid)
  185. Renderer::setPass(*mSolidMaterial.proxy, 0);
  186. else
  187. Renderer::setPass(*mWireMaterial.proxy, 0);
  188. }
  189. for (auto& meshData : mMeshes)
  190. {
  191. if (currentType != meshData.type)
  192. {
  193. if (meshData.type == MeshType::Solid)
  194. Renderer::setPass(*mSolidMaterial.proxy, 0);
  195. else
  196. Renderer::setPass(*mWireMaterial.proxy, 0);
  197. currentType = meshData.type;
  198. }
  199. Renderer::draw(meshData.mesh, meshData.mesh->getProperties().getSubMesh(0));
  200. }
  201. }
  202. }