BsHandleDrawManager.cpp 12 KB

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