BsHandleDrawManager.cpp 12 KB

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