2
0

BsDebugDraw.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include "BsDebugDraw.h"
  2. #include "CmMesh.h"
  3. #include "CmTime.h"
  4. #include "CmVector2.h"
  5. #include "CmMaterial.h"
  6. #include "CmPass.h"
  7. #include "CmApplication.h"
  8. using namespace CamelotFramework;
  9. namespace BansheeEngine
  10. {
  11. DebugDraw::DebugDraw()
  12. {
  13. // TODO - Create a fixed sized mesh and prevent updating the mesh completely every frame
  14. mTriangleMesh = Mesh::create();
  15. mLineMesh = Mesh::create();
  16. // TODO - Init materials
  17. //HMaterial mTriangleMaterial;
  18. //HMaterial mLineMaterial;
  19. }
  20. void DebugDraw::draw2DLine(const Vector2&a, const Vector2& b, const Color& color, float timeout)
  21. {
  22. UINT32* indices = cm_newN<UINT32, ScratchAlloc>(2);
  23. UINT8* vertices = (UINT8*)cm_alloc<ScratchAlloc>(2 * VertexSize);
  24. DebugDrawCommand command;
  25. command.indices = cm_newN<UINT32, ScratchAlloc>(2);
  26. command.vertices = (UINT8*)cm_alloc<ScratchAlloc>(2 * VertexSize);
  27. command.numElements = 1;
  28. command.type = DebugDrawType::Line;
  29. command.timeEnds = gTime().getTime() + timeout;
  30. command.indices[0] = 0;
  31. command.indices[1] = 1;
  32. UINT8* vertDst = command.vertices;
  33. RGBA color32 = color.getAsRGBA();
  34. Vector3 pointA(a.x, a.y, 0.0f);
  35. memcpy(vertDst, &pointA, sizeof(pointA));
  36. vertDst += sizeof(pointA);
  37. memcpy(vertDst, &color32, sizeof(color32));
  38. vertDst += sizeof(color32);
  39. Vector3 pointB(b.x, b.y, 0.0f);
  40. memcpy(vertDst, &pointB, sizeof(pointB));
  41. vertDst += sizeof(pointB);
  42. memcpy(vertDst, &color32, sizeof(color32));
  43. vertDst += sizeof(color32);
  44. mCommands.push_back(command);
  45. }
  46. void DebugDraw::updateMeshes()
  47. {
  48. if(mCommands.size() == 0)
  49. return;
  50. UINT32 totalNumLineIndices = 0;
  51. UINT32 totalNumLineVertices = 0;
  52. UINT32 totalNumTriangleIndices = 0;
  53. UINT32 totalNumTriangleVertices = 0;
  54. for(auto& command : mCommands)
  55. {
  56. if(command.type == DebugDrawType::Line)
  57. {
  58. totalNumLineIndices += command.numElements * 2;
  59. totalNumLineVertices += command.numElements * 2;
  60. }
  61. else if(command.type == DebugDrawType::Triangle)
  62. {
  63. totalNumTriangleIndices += command.numElements * 3;
  64. totalNumTriangleVertices += command.numElements * 3;
  65. }
  66. }
  67. // TODO - Somehow avoid creating these every frame?
  68. MeshDataPtr lineMeshData = cm_shared_ptr<MeshData, ScratchAlloc>(totalNumLineVertices);
  69. MeshDataPtr triangleMeshData = cm_shared_ptr<MeshData, ScratchAlloc>(totalNumTriangleVertices);
  70. lineMeshData->beginDesc();
  71. lineMeshData->addSubMesh(totalNumLineIndices);
  72. lineMeshData->addVertElem(VET_FLOAT3, VES_POSITION);
  73. lineMeshData->addVertElem(VET_COLOR, VES_COLOR);
  74. lineMeshData->endDesc();
  75. triangleMeshData->beginDesc();
  76. triangleMeshData->addSubMesh(totalNumTriangleIndices);
  77. triangleMeshData->addVertElem(VET_FLOAT3, VES_POSITION);
  78. triangleMeshData->addVertElem(VET_COLOR, VES_COLOR);
  79. triangleMeshData->endDesc();
  80. UINT32 lineIndexOffset = 0;
  81. UINT32 lineVertexOffset = 0;
  82. UINT32 triangleIndexOffset = 0;
  83. UINT32 triangleVertexOffset = 0;
  84. Vector<DebugDrawCommand>::type newCommands;
  85. for(auto& command : mCommands)
  86. {
  87. if(command.type == DebugDrawType::Line)
  88. {
  89. UINT32 numIndices = command.numElements * 2;
  90. UINT32 numVertices = command.numElements * 2;
  91. UINT32* indexData = lineMeshData->getIndices32() + lineIndexOffset;
  92. memcpy(indexData, command.indices, numIndices * sizeof(UINT32));
  93. UINT8* vertexData = lineMeshData->getElementData(VES_POSITION) + lineVertexOffset * VertexSize;
  94. memcpy(vertexData, command.vertices, numVertices * VertexSize);
  95. lineIndexOffset += numIndices;
  96. lineVertexOffset += numVertices;
  97. }
  98. else if(command.type == DebugDrawType::Triangle)
  99. {
  100. UINT32 numIndices = command.numElements * 3;
  101. UINT32 numVertices = command.numElements * 3;
  102. UINT32* indexData = triangleMeshData->getIndices32() + triangleIndexOffset;
  103. memcpy(indexData, command.indices, numIndices * sizeof(UINT32));
  104. UINT8* vertexData = triangleMeshData->getElementData(VES_POSITION) + triangleVertexOffset * VertexSize;
  105. memcpy(vertexData, command.vertices, numVertices * VertexSize);
  106. triangleIndexOffset += numIndices;
  107. triangleVertexOffset += numVertices;
  108. }
  109. if(command.timeEnds < gTime().getTime())
  110. newCommands.push_back(command);
  111. else
  112. {
  113. UINT32 numIndices = 0;
  114. if(command.type == DebugDrawType::Line)
  115. {
  116. numIndices = command.numElements * 2;
  117. }
  118. else if(command.type == DebugDrawType::Triangle)
  119. {
  120. numIndices = command.numElements * 3;
  121. }
  122. cm_deleteN<ScratchAlloc>(command.indices, numIndices);
  123. cm_free<ScratchAlloc>(command.vertices);
  124. }
  125. }
  126. gMainSyncedCA().writeSubresource(mLineMesh.getInternalPtr(), 0, *lineMeshData);
  127. gMainSyncedCA().writeSubresource(mTriangleMesh.getInternalPtr(), 0, *triangleMeshData);
  128. gMainSyncedCA().submitToCoreThread(true);
  129. }
  130. void DebugDraw::render(const Camera* camera, CoreAccessor& coreAccessor)
  131. {
  132. if(mCommands.size() == 0)
  133. return;
  134. updateMeshes();
  135. for(UINT32 i = 0; i < mLineMaterial->getNumPasses(); i++)
  136. {
  137. PassPtr pass = mLineMaterial->getPass(i);
  138. pass->activate(coreAccessor);
  139. PassParametersPtr paramsPtr = mLineMaterial->getPassParameters(i);
  140. pass->bindParameters(coreAccessor, paramsPtr);
  141. coreAccessor.render(mLineMesh->getRenderOperation());
  142. }
  143. for(UINT32 i = 0; i < mTriangleMaterial->getNumPasses(); i++)
  144. {
  145. PassPtr pass = mTriangleMaterial->getPass(i);
  146. pass->activate(coreAccessor);
  147. PassParametersPtr paramsPtr = mTriangleMaterial->getPassParameters(i);
  148. pass->bindParameters(coreAccessor, paramsPtr);
  149. coreAccessor.render(mTriangleMesh->getRenderOperation());
  150. }
  151. }
  152. //void DebugDraw::drawAABB(const AxisAlignedBox& aab, const Color& color, float timeout)
  153. //{
  154. //}
  155. //void DebugDraw::drawSphere(const Vector3& center, float radius, const Color& color, float timeout)
  156. //{
  157. //}
  158. }