BsHandleDrawManager.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  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 "BsCoreRenderer.h"
  8. #include "BsTransientMesh.h"
  9. #include "BsCamera.h"
  10. #include "BsRendererUtility.h"
  11. #include "BsSceneObject.h"
  12. #include "BsTime.h"
  13. using namespace std::placeholders;
  14. namespace BansheeEngine
  15. {
  16. const UINT32 HandleDrawManager::SPHERE_QUALITY = 1;
  17. const UINT32 HandleDrawManager::WIRE_SPHERE_QUALITY = 10;
  18. const UINT32 HandleDrawManager::ARC_QUALITY = 10;
  19. HandleDrawManager::HandleDrawManager()
  20. :mCore(nullptr), mLastFrameIdx((UINT64)-1)
  21. {
  22. mTransform = Matrix4::IDENTITY;
  23. mDrawHelper = bs_new<DrawHelper>();
  24. HMaterial solidMaterial = BuiltinEditorResources::instance().createSolidHandleMat();
  25. HMaterial wireMaterial = BuiltinEditorResources::instance().createWireHandleMat();
  26. HMaterial clearMaterial = BuiltinEditorResources::instance().createHandleClearAlphaMat();
  27. SPtr<MaterialCore> solidMaterialProxy = solidMaterial->getCore();
  28. SPtr<MaterialCore> wireMaterialProxy = wireMaterial->getCore();
  29. SPtr<MaterialCore> clearMaterialProxy = clearMaterial->getCore();
  30. mCore.store(bs_new<HandleDrawManagerCore>(HandleDrawManagerCore::PrivatelyConstruct()), std::memory_order_release);
  31. gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::initializeCore, this,
  32. wireMaterialProxy, solidMaterialProxy, clearMaterialProxy));
  33. }
  34. HandleDrawManager::~HandleDrawManager()
  35. {
  36. clearMeshes();
  37. bs_delete(mDrawHelper);
  38. gCoreAccessor().queueCommand(std::bind(&HandleDrawManager::destroyCore, this, mCore.load(std::memory_order_relaxed)));
  39. }
  40. void HandleDrawManager::initializeCore(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat,
  41. const SPtr<MaterialCore>& clearMat)
  42. {
  43. THROW_IF_NOT_CORE_THREAD;
  44. mCore.load(std::memory_order_acquire)->initialize(wireMat, solidMat, clearMat);
  45. }
  46. void HandleDrawManager::destroyCore(HandleDrawManagerCore* core)
  47. {
  48. THROW_IF_NOT_CORE_THREAD;
  49. bs_delete(core);
  50. }
  51. void HandleDrawManager::setColor(const Color& color)
  52. {
  53. mDrawHelper->setColor(color);
  54. }
  55. void HandleDrawManager::setTransform(const Matrix4& transform)
  56. {
  57. mTransform = transform;
  58. }
  59. void HandleDrawManager::setLayer(UINT64 layer)
  60. {
  61. mDrawHelper->setLayer(layer);
  62. }
  63. void HandleDrawManager::drawCube(const Vector3& position, const Vector3& extents, float size)
  64. {
  65. Matrix4 scale = Matrix4::scaling(size);
  66. mDrawHelper->setTransform(mTransform * scale);
  67. mDrawHelper->cube(position, extents);
  68. }
  69. void HandleDrawManager::drawSphere(const Vector3& position, float radius, float size)
  70. {
  71. Matrix4 scale = Matrix4::scaling(size);
  72. mDrawHelper->setTransform(mTransform * scale);
  73. mDrawHelper->sphere(position, radius);
  74. }
  75. void HandleDrawManager::drawWireCube(const Vector3& position, const Vector3& extents, float size)
  76. {
  77. Matrix4 scale = Matrix4::scaling(size);
  78. mDrawHelper->setTransform(mTransform * scale);
  79. mDrawHelper->wireCube(position, extents);
  80. }
  81. void HandleDrawManager::drawWireSphere(const Vector3& position, float radius, float size)
  82. {
  83. Matrix4 scale = Matrix4::scaling(size);
  84. mDrawHelper->setTransform(mTransform * scale);
  85. mDrawHelper->wireSphere(position, radius);
  86. }
  87. void HandleDrawManager::drawCone(const Vector3& base, const Vector3& normal, float height, float radius, float size)
  88. {
  89. Matrix4 scale = Matrix4::scaling(size);
  90. mDrawHelper->setTransform(mTransform * scale);
  91. mDrawHelper->cone(base, normal, height, radius);
  92. }
  93. void HandleDrawManager::drawLine(const Vector3& start, const Vector3& end, float size)
  94. {
  95. Matrix4 scale = Matrix4::scaling(size);
  96. mDrawHelper->setTransform(mTransform * scale);
  97. mDrawHelper->line(start, end);
  98. }
  99. void HandleDrawManager::drawDisc(const Vector3& position, const Vector3& normal, float radius, float size)
  100. {
  101. Matrix4 scale = Matrix4::scaling(size);
  102. mDrawHelper->setTransform(mTransform * scale);
  103. mDrawHelper->disc(position, normal, radius);
  104. }
  105. void HandleDrawManager::drawWireDisc(const Vector3& position, const Vector3& normal, float radius, float size)
  106. {
  107. Matrix4 scale = Matrix4::scaling(size);
  108. mDrawHelper->setTransform(mTransform * scale);
  109. mDrawHelper->wireDisc(position, normal, radius);
  110. }
  111. void HandleDrawManager::drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size)
  112. {
  113. Matrix4 scale = Matrix4::scaling(size);
  114. mDrawHelper->setTransform(mTransform * scale);
  115. mDrawHelper->arc(position, normal, radius, startAngle, amountAngle);
  116. }
  117. void HandleDrawManager::drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size)
  118. {
  119. Matrix4 scale = Matrix4::scaling(size);
  120. mDrawHelper->setTransform(mTransform * scale);
  121. mDrawHelper->wireArc(position, normal, radius, startAngle, amountAngle);
  122. }
  123. void HandleDrawManager::drawRect(const Rect3& area, float size)
  124. {
  125. Matrix4 scale = Matrix4::scaling(size);
  126. mDrawHelper->setTransform(mTransform * scale);
  127. mDrawHelper->rectangle(area);
  128. }
  129. void HandleDrawManager::draw(const CameraPtr& camera)
  130. {
  131. HandleDrawManagerCore* core = mCore.load(std::memory_order_relaxed);
  132. // Clear meshes from previous frame
  133. UINT64 frameIdx = gTime().getFrameIdx();
  134. if(frameIdx != mLastFrameIdx)
  135. {
  136. gCoreAccessor().queueCommand(std::bind(&HandleDrawManagerCore::clearQueued, core));
  137. clearMeshes();
  138. mLastFrameIdx = frameIdx;
  139. }
  140. mDrawHelper->buildMeshes(DrawHelper::SortType::BackToFront, camera->getPosition(), camera->getLayers());
  141. const Vector<DrawHelper::ShapeMeshData>& meshes = mDrawHelper->getMeshes();
  142. mActiveMeshes.push_back(meshes);
  143. Vector<HandleDrawManagerCore::MeshData> proxyData;
  144. for (auto& meshData : meshes)
  145. {
  146. if (meshData.type == DrawHelper::MeshType::Solid)
  147. {
  148. proxyData.push_back(HandleDrawManagerCore::MeshData(
  149. meshData.mesh->getCore(), HandleDrawManagerCore::MeshType::Solid));
  150. }
  151. else // Wire
  152. {
  153. proxyData.push_back(HandleDrawManagerCore::MeshData(
  154. meshData.mesh->getCore(), HandleDrawManagerCore::MeshType::Wire));
  155. }
  156. }
  157. gCoreAccessor().queueCommand(std::bind(&HandleDrawManagerCore::queueForDraw, core, camera->getCore(), proxyData));
  158. }
  159. void HandleDrawManager::clear()
  160. {
  161. mDrawHelper->clear();
  162. }
  163. void HandleDrawManager::clearMeshes()
  164. {
  165. for (auto entry : mActiveMeshes)
  166. mDrawHelper->clearMeshes(entry);
  167. mActiveMeshes.clear();
  168. }
  169. HandleDrawManagerCore::~HandleDrawManagerCore()
  170. {
  171. clearQueued();
  172. }
  173. void HandleDrawManagerCore::initialize(const SPtr<MaterialCore>& wireMat, const SPtr<MaterialCore>& solidMat,
  174. const SPtr<MaterialCore>& clearMat)
  175. {
  176. {
  177. mWireMaterial.mat = wireMat;
  178. SPtr<GpuParamsCore> vertParams = wireMat->getPassParameters(0)->mVertParams;
  179. vertParams->getParam("matViewProj", mWireMaterial.mViewProj);
  180. }
  181. {
  182. mSolidMaterial.mat = solidMat;
  183. SPtr<GpuParamsCore> vertParams = solidMat->getPassParameters(0)->mVertParams;
  184. SPtr<GpuParamsCore> fragParams = solidMat->getPassParameters(0)->mFragParams;
  185. vertParams->getParam("matViewProj", mSolidMaterial.mViewProj);
  186. fragParams->getParam("viewDir", mSolidMaterial.mViewDir);
  187. }
  188. {
  189. mClearMaterial.mat = clearMat;
  190. }
  191. }
  192. void HandleDrawManagerCore::queueForDraw(const SPtr<CameraCore>& camera, const Vector<MeshData>& meshes)
  193. {
  194. CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
  195. if (camera != nullptr)
  196. {
  197. UINT32 idx = (UINT32)mQueuedData.size();
  198. mQueuedData.push_back({ camera, meshes });
  199. activeRenderer->_registerRenderCallback(camera.get(), 20, std::bind(&HandleDrawManagerCore::render, this, idx));
  200. }
  201. }
  202. void HandleDrawManagerCore::clearQueued()
  203. {
  204. CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
  205. for (auto& entry : mQueuedData)
  206. activeRenderer->_unregisterRenderCallback(entry.camera.get(), 20);
  207. mQueuedData.clear();
  208. }
  209. void HandleDrawManagerCore::render(UINT32 queuedDataIdx)
  210. {
  211. THROW_IF_NOT_CORE_THREAD;
  212. const QueuedData& queueData = mQueuedData[queuedDataIdx];
  213. SPtr<CameraCore> camera = queueData.camera;
  214. const Vector<MeshData>& meshes = queueData.meshes;
  215. SPtr<RenderTargetCore> renderTarget = camera->getViewport()->getTarget();
  216. float width = (float)renderTarget->getProperties().getWidth();
  217. float height = (float)renderTarget->getProperties().getHeight();
  218. Rect2 normArea = camera->getViewport()->getNormArea();
  219. Rect2I screenArea;
  220. screenArea.x = (int)(normArea.x * width);
  221. screenArea.y = (int)(normArea.y * height);
  222. screenArea.width = (int)(normArea.width * width);
  223. screenArea.height = (int)(normArea.height * height);
  224. Matrix4 viewProjMat = camera->getProjectionMatrixRS() * camera->getViewMatrix();
  225. mSolidMaterial.mViewProj.set(viewProjMat);
  226. mSolidMaterial.mViewDir.set((Vector4)camera->getForward());
  227. mWireMaterial.mViewProj.set(viewProjMat);
  228. MeshType currentType = MeshType::Solid;
  229. if (meshes.size() > 0)
  230. {
  231. currentType = meshes[0].type;
  232. if (currentType == MeshType::Solid)
  233. gRendererUtility().setPass(mSolidMaterial.mat, 0);
  234. else
  235. gRendererUtility().setPass(mWireMaterial.mat, 0);
  236. }
  237. for (auto& meshData : meshes)
  238. {
  239. if (currentType != meshData.type)
  240. {
  241. if (meshData.type == MeshType::Solid)
  242. gRendererUtility().setPass(mSolidMaterial.mat, 0);
  243. else
  244. gRendererUtility().setPass(mWireMaterial.mat, 0);
  245. currentType = meshData.type;
  246. }
  247. gRendererUtility().draw(meshData.mesh, meshData.mesh->getProperties().getSubMesh(0));
  248. }
  249. // Set alpha of everything that was drawn to 1 so we can overlay this texture onto GUI using transparency
  250. gRendererUtility().setPass(mClearMaterial.mat, 0);
  251. gRendererUtility().drawScreenQuad(*camera->getViewport());
  252. }
  253. }