BsHandleDrawManager.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Handles/BsHandleDrawManager.h"
  4. #include "Utility/BsDrawHelper.h"
  5. #include "Material/BsMaterial.h"
  6. #include "Material/BsGpuParamsSet.h"
  7. #include "Utility/BsBuiltinEditorResources.h"
  8. #include "CoreThread/BsCoreThread.h"
  9. #include "Renderer/BsRendererManager.h"
  10. #include "Renderer/BsRenderer.h"
  11. #include "Mesh/BsMesh.h"
  12. #include "Renderer/BsCamera.h"
  13. #include "Renderer/BsRendererUtility.h"
  14. #include "Image/BsTexture.h"
  15. #include "Utility/BsTime.h"
  16. #include "RenderAPI/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)
  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. ct::HandleRenderer::InitData rendererInitData;
  33. rendererInitData.solidMat = solidMaterial->getCore();
  34. rendererInitData.lineMat = lineMaterial->getCore();
  35. rendererInitData.textMat = textMaterial->getCore();
  36. rendererInitData.clearMat = clearMaterial->getCore();
  37. mRenderer = RendererExtension::create<ct::HandleRenderer>(rendererInitData);
  38. }
  39. HandleDrawManager::~HandleDrawManager()
  40. {
  41. clearMeshes();
  42. bs_delete(mDrawHelper);
  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::setLayer(UINT64 layer)
  53. {
  54. mDrawHelper->setLayer(layer);
  55. }
  56. void HandleDrawManager::drawCube(const Vector3& position, const Vector3& extents, float size)
  57. {
  58. Matrix4 scale = Matrix4::scaling(size);
  59. mDrawHelper->setTransform(mTransform * scale);
  60. mDrawHelper->cube(position, extents);
  61. }
  62. void HandleDrawManager::drawSphere(const Vector3& position, float radius, float size)
  63. {
  64. Matrix4 scale = Matrix4::scaling(size);
  65. mDrawHelper->setTransform(mTransform * scale);
  66. mDrawHelper->sphere(position, radius);
  67. }
  68. void HandleDrawManager::drawWireCube(const Vector3& position, const Vector3& extents, float size)
  69. {
  70. Matrix4 scale = Matrix4::scaling(size);
  71. mDrawHelper->setTransform(mTransform * scale);
  72. mDrawHelper->wireCube(position, extents);
  73. }
  74. void HandleDrawManager::drawWireSphere(const Vector3& position, float radius, float size)
  75. {
  76. Matrix4 scale = Matrix4::scaling(size);
  77. mDrawHelper->setTransform(mTransform * scale);
  78. mDrawHelper->wireSphere(position, radius);
  79. }
  80. void HandleDrawManager::drawCone(const Vector3& base, const Vector3& normal, float height, float radius, float size)
  81. {
  82. Matrix4 scale = Matrix4::scaling(size);
  83. mDrawHelper->setTransform(mTransform * scale);
  84. mDrawHelper->cone(base, normal, height, radius);
  85. }
  86. void HandleDrawManager::drawLine(const Vector3& start, const Vector3& end, float size)
  87. {
  88. Matrix4 scale = Matrix4::scaling(size);
  89. mDrawHelper->setTransform(mTransform * scale);
  90. mDrawHelper->line(start, end);
  91. }
  92. void HandleDrawManager::drawDisc(const Vector3& position, const Vector3& normal, float radius, float size)
  93. {
  94. Matrix4 scale = Matrix4::scaling(size);
  95. mDrawHelper->setTransform(mTransform * scale);
  96. mDrawHelper->disc(position, normal, radius);
  97. }
  98. void HandleDrawManager::drawWireDisc(const Vector3& position, const Vector3& normal, float radius, float size)
  99. {
  100. Matrix4 scale = Matrix4::scaling(size);
  101. mDrawHelper->setTransform(mTransform * scale);
  102. mDrawHelper->wireDisc(position, normal, radius);
  103. }
  104. void HandleDrawManager::drawArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size)
  105. {
  106. Matrix4 scale = Matrix4::scaling(size);
  107. mDrawHelper->setTransform(mTransform * scale);
  108. mDrawHelper->arc(position, normal, radius, startAngle, amountAngle);
  109. }
  110. void HandleDrawManager::drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle, float size)
  111. {
  112. Matrix4 scale = Matrix4::scaling(size);
  113. mDrawHelper->setTransform(mTransform * scale);
  114. mDrawHelper->wireArc(position, normal, radius, startAngle, amountAngle);
  115. }
  116. void HandleDrawManager::drawRect(const Rect3& area, float size)
  117. {
  118. Matrix4 scale = Matrix4::scaling(size);
  119. mDrawHelper->setTransform(mTransform * scale);
  120. mDrawHelper->rectangle(area);
  121. }
  122. void HandleDrawManager::drawText(const Vector3& position, const String& text, const HFont& font, UINT32 fontSize)
  123. {
  124. mDrawHelper->setTransform(mTransform);
  125. HFont myFont = font;
  126. if (myFont == nullptr)
  127. myFont = BuiltinEditorResources::instance().getDefaultAAFont();
  128. mDrawHelper->text(position, text, myFont, fontSize);
  129. }
  130. void HandleDrawManager::draw(const SPtr<Camera>& camera)
  131. {
  132. ct::HandleRenderer* renderer = mRenderer.get();
  133. // Clear meshes from previous frame
  134. UINT64 frameIdx = gTime().getFrameIdx();
  135. if(frameIdx != mLastFrameIdx)
  136. {
  137. gCoreThread().queueCommand(std::bind(&ct::HandleRenderer::clearQueued, renderer));
  138. clearMeshes();
  139. mLastFrameIdx = frameIdx;
  140. }
  141. const Vector<DrawHelper::ShapeMeshData>& meshes =
  142. mDrawHelper->buildMeshes(DrawHelper::SortType::BackToFront, camera.get(), camera->getLayers());
  143. mActiveMeshes.push_back(meshes);
  144. Vector<ct::HandleRenderer::MeshData> proxyData;
  145. for (auto& meshData : meshes)
  146. {
  147. SPtr<ct::Texture> tex;
  148. if (meshData.texture.isLoaded())
  149. tex = meshData.texture->getCore();
  150. if (meshData.type == DrawHelper::MeshType::Solid)
  151. {
  152. proxyData.push_back(ct::HandleRenderer::MeshData(
  153. meshData.mesh->getCore(), meshData.subMesh, tex, ct::HandleRenderer::MeshType::Solid));
  154. }
  155. else if (meshData.type == DrawHelper::MeshType::Line)
  156. {
  157. proxyData.push_back(ct::HandleRenderer::MeshData(
  158. meshData.mesh->getCore(), meshData.subMesh, tex, ct::HandleRenderer::MeshType::Line));
  159. }
  160. else // Text
  161. {
  162. proxyData.push_back(ct::HandleRenderer::MeshData(
  163. meshData.mesh->getCore(), meshData.subMesh, tex, ct::HandleRenderer::MeshType::Text));
  164. }
  165. }
  166. gCoreThread().queueCommand(std::bind(&ct::HandleRenderer::queueForDraw, renderer, camera->getCore(), proxyData));
  167. }
  168. void HandleDrawManager::clear()
  169. {
  170. mDrawHelper->clear();
  171. }
  172. void HandleDrawManager::clearMeshes()
  173. {
  174. mActiveMeshes.clear();
  175. }
  176. namespace ct
  177. {
  178. HandleParamBlockDef gHandleParamBlockDef;
  179. HandleRenderer::HandleRenderer()
  180. :RendererExtension(RenderLocation::PostLightPass, -20), mTypeCounters()
  181. { }
  182. void HandleRenderer::initialize(const Any& data)
  183. {
  184. const InitData& initData = any_cast_ref<InitData>(data);
  185. mMaterials[(UINT32)MeshType::Line] = initData.lineMat;
  186. mMaterials[(UINT32)MeshType::Solid] = initData.solidMat;
  187. mMaterials[(UINT32)MeshType::Text] = initData.textMat;
  188. mClearMaterial = initData.clearMat;
  189. mMaterials[(UINT32)MeshType::Line]->getTechnique(0)->compile();
  190. mMaterials[(UINT32)MeshType::Solid]->getTechnique(0)->compile();
  191. mMaterials[(UINT32)MeshType::Text]->getTechnique(0)->compile();
  192. mClearMaterial->getTechnique(0)->compile();
  193. mParamBuffer = gHandleParamBlockDef.createBuffer();
  194. }
  195. void HandleRenderer::destroy()
  196. {
  197. clearQueued();
  198. }
  199. void HandleRenderer::queueForDraw(const SPtr<Camera>& camera, Vector<MeshData>& meshes)
  200. {
  201. SPtr<Renderer> activeRenderer = RendererManager::instance().getActive();
  202. if (camera != nullptr)
  203. {
  204. for(auto& entry : meshes)
  205. {
  206. UINT32 typeIdx = (UINT32)entry.type;
  207. UINT32 paramsIdx = mTypeCounters[typeIdx];
  208. entry.paramIdx = paramsIdx;
  209. SPtr<GpuParamsSet> paramsSet;
  210. if (paramsIdx >= mParamSets[typeIdx].size())
  211. {
  212. paramsSet = mMaterials[typeIdx]->createParamsSet();
  213. paramsSet->setParamBlockBuffer("Uniforms", mParamBuffer, true);
  214. mParamSets[typeIdx].push_back(paramsSet);
  215. }
  216. else
  217. paramsSet = mParamSets[typeIdx][entry.paramIdx];
  218. if(entry.type == MeshType::Text)
  219. {
  220. GpuParamTexture texture;
  221. paramsSet->getGpuParams()->getTextureParam(GPT_FRAGMENT_PROGRAM, "gMainTexture", texture);
  222. texture.set(entry.texture);
  223. }
  224. mTypeCounters[typeIdx]++;
  225. }
  226. mQueuedData.push_back({ camera, meshes });
  227. }
  228. }
  229. void HandleRenderer::clearQueued()
  230. {
  231. mQueuedData.clear();
  232. bs_zero_out(mTypeCounters);
  233. }
  234. RendererExtensionRequest HandleRenderer::check(const Camera& camera)
  235. {
  236. for(auto& entry : mQueuedData)
  237. {
  238. if (entry.camera.get() == &camera)
  239. return RendererExtensionRequest::ForceRender;
  240. }
  241. return RendererExtensionRequest::DontRender;
  242. }
  243. void HandleRenderer::render(const Camera& camera, const RendererViewContext& viewContext)
  244. {
  245. THROW_IF_NOT_CORE_THREAD;
  246. for (auto& entry : mQueuedData)
  247. {
  248. if (entry.camera.get() != &camera)
  249. continue;
  250. const QueuedData& queueData = entry;
  251. const Vector<MeshData>& meshes = queueData.meshes;
  252. SPtr<RenderTarget> renderTarget = camera.getViewport()->getTarget();
  253. Matrix4 viewProjMat = camera.getProjectionMatrixRS() * camera.getViewMatrix();
  254. float invViewportWidth = 1.0f / (camera.getViewport()->getPixelArea().width * 0.5f);
  255. float invViewportHeight = 1.0f / (camera.getViewport()->getPixelArea().height * 0.5f);
  256. float viewportYFlip = (gCaps().conventions.ndcYAxis == Conventions::Axis::Down) ? -1.0f : 1.0f;
  257. gHandleParamBlockDef.gMatViewProj.set(mParamBuffer, viewProjMat);
  258. gHandleParamBlockDef.gViewDir.set(mParamBuffer, (Vector4)camera.getTransform().getForward());
  259. gHandleParamBlockDef.gInvViewportWidth.set(mParamBuffer, invViewportWidth);
  260. gHandleParamBlockDef.gInvViewportHeight.set(mParamBuffer, invViewportHeight);
  261. gHandleParamBlockDef.gViewportYFlip.set(mParamBuffer, viewportYFlip);
  262. UINT32 currentType = -1;
  263. for (auto& meshData : meshes)
  264. {
  265. UINT32 typeIdx = (UINT32)meshData.type;
  266. if (currentType != typeIdx)
  267. {
  268. gRendererUtility().setPass(mMaterials[typeIdx]);
  269. currentType = typeIdx;
  270. }
  271. gRendererUtility().setPassParams(mParamSets[typeIdx][meshData.paramIdx]);
  272. gRendererUtility().draw(meshData.mesh, meshData.subMesh);
  273. }
  274. // Set alpha of everything that was drawn to 1 so we can overlay this texture onto GUI using transparency
  275. gRendererUtility().setPass(mClearMaterial, 0);
  276. gRendererUtility().drawScreenQuad();
  277. }
  278. }
  279. }
  280. }