BsHandleDrawManager.cpp 12 KB

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