DebugDrawer.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Scene/DebugDrawer.h>
  6. #include <AnKi/Resource/ResourceManager.h>
  7. #include <AnKi/Renderer/RenderQueue.h>
  8. #include <AnKi/Core/StagingGpuMemoryManager.h>
  9. #include <AnKi/Physics/PhysicsWorld.h>
  10. #include <AnKi/Gr/Buffer.h>
  11. #include <AnKi/Collision.h>
  12. namespace anki
  13. {
  14. void allocateAndPopulateDebugBox(StagingGpuMemoryManager& stagingGpuAllocator, StagingGpuMemoryToken& vertsToken,
  15. StagingGpuMemoryToken& indicesToken, U32& indexCount)
  16. {
  17. Vec3* verts = static_cast<Vec3*>(
  18. stagingGpuAllocator.allocateFrame(sizeof(Vec3) * 8, StagingGpuMemoryType::VERTEX, vertsToken));
  19. const F32 SIZE = 1.0f;
  20. verts[0] = Vec3(SIZE, SIZE, SIZE); // front top right
  21. verts[1] = Vec3(-SIZE, SIZE, SIZE); // front top left
  22. verts[2] = Vec3(-SIZE, -SIZE, SIZE); // front bottom left
  23. verts[3] = Vec3(SIZE, -SIZE, SIZE); // front bottom right
  24. verts[4] = Vec3(SIZE, SIZE, -SIZE); // back top right
  25. verts[5] = Vec3(-SIZE, SIZE, -SIZE); // back top left
  26. verts[6] = Vec3(-SIZE, -SIZE, -SIZE); // back bottom left
  27. verts[7] = Vec3(SIZE, -SIZE, -SIZE); // back bottom right
  28. const U INDEX_COUNT = 12 * 2;
  29. U16* indices = static_cast<U16*>(
  30. stagingGpuAllocator.allocateFrame(sizeof(U16) * INDEX_COUNT, StagingGpuMemoryType::VERTEX, indicesToken));
  31. U c = 0;
  32. indices[c++] = 0;
  33. indices[c++] = 1;
  34. indices[c++] = 1;
  35. indices[c++] = 2;
  36. indices[c++] = 2;
  37. indices[c++] = 3;
  38. indices[c++] = 3;
  39. indices[c++] = 0;
  40. indices[c++] = 4;
  41. indices[c++] = 5;
  42. indices[c++] = 5;
  43. indices[c++] = 6;
  44. indices[c++] = 6;
  45. indices[c++] = 7;
  46. indices[c++] = 7;
  47. indices[c++] = 4;
  48. indices[c++] = 0;
  49. indices[c++] = 4;
  50. indices[c++] = 1;
  51. indices[c++] = 5;
  52. indices[c++] = 2;
  53. indices[c++] = 6;
  54. indices[c++] = 3;
  55. indices[c++] = 7;
  56. ANKI_ASSERT(c == INDEX_COUNT);
  57. indexCount = INDEX_COUNT;
  58. }
  59. Error DebugDrawer2::init(ResourceManager* rsrcManager)
  60. {
  61. ANKI_CHECK(rsrcManager->loadResource("Shaders/SceneDebug.ankiprog", m_prog));
  62. {
  63. BufferInitInfo bufferInit("DebugCube");
  64. bufferInit.m_usage = BufferUsageBit::VERTEX;
  65. bufferInit.m_size = sizeof(Vec3) * 8;
  66. bufferInit.m_mapAccess = BufferMapAccessBit::WRITE;
  67. m_cubePositionsBuffer = rsrcManager->getGrManager().newBuffer(bufferInit);
  68. Vec3* verts = static_cast<Vec3*>(m_cubePositionsBuffer->map(0, MAX_PTR_SIZE, BufferMapAccessBit::WRITE));
  69. const F32 size = 1.0f;
  70. verts[0] = Vec3(size, size, size); // front top right
  71. verts[1] = Vec3(-size, size, size); // front top left
  72. verts[2] = Vec3(-size, -size, size); // front bottom left
  73. verts[3] = Vec3(size, -size, size); // front bottom right
  74. verts[4] = Vec3(size, size, -size); // back top right
  75. verts[5] = Vec3(-size, size, -size); // back top left
  76. verts[6] = Vec3(-size, -size, -size); // back bottom left
  77. verts[7] = Vec3(size, -size, -size); // back bottom right
  78. m_cubePositionsBuffer->flush(0, MAX_PTR_SIZE);
  79. m_cubePositionsBuffer->unmap();
  80. }
  81. {
  82. constexpr U INDEX_COUNT = 12 * 2;
  83. BufferInitInfo bufferInit("DebugCube");
  84. bufferInit.m_usage = BufferUsageBit::VERTEX;
  85. bufferInit.m_size = sizeof(U16) * INDEX_COUNT;
  86. bufferInit.m_mapAccess = BufferMapAccessBit::WRITE;
  87. m_cubeIndicesBuffer = rsrcManager->getGrManager().newBuffer(bufferInit);
  88. U16* indices = static_cast<U16*>(m_cubeIndicesBuffer->map(0, MAX_PTR_SIZE, BufferMapAccessBit::WRITE));
  89. U32 indexCount = 0;
  90. indices[indexCount++] = 0;
  91. indices[indexCount++] = 1;
  92. indices[indexCount++] = 1;
  93. indices[indexCount++] = 2;
  94. indices[indexCount++] = 2;
  95. indices[indexCount++] = 3;
  96. indices[indexCount++] = 3;
  97. indices[indexCount++] = 0;
  98. indices[indexCount++] = 4;
  99. indices[indexCount++] = 5;
  100. indices[indexCount++] = 5;
  101. indices[indexCount++] = 6;
  102. indices[indexCount++] = 6;
  103. indices[indexCount++] = 7;
  104. indices[indexCount++] = 7;
  105. indices[indexCount++] = 4;
  106. indices[indexCount++] = 0;
  107. indices[indexCount++] = 4;
  108. indices[indexCount++] = 1;
  109. indices[indexCount++] = 5;
  110. indices[indexCount++] = 2;
  111. indices[indexCount++] = 6;
  112. indices[indexCount++] = 3;
  113. indices[indexCount++] = 7;
  114. m_cubeIndicesBuffer->flush(0, MAX_PTR_SIZE);
  115. m_cubeIndicesBuffer->unmap();
  116. }
  117. return Error::NONE;
  118. }
  119. void DebugDrawer2::drawCubes(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 lineSize, Bool ditherFailedDepth,
  120. F32 cubeSideSize, StagingGpuMemoryManager& stagingGpuAllocator,
  121. CommandBufferPtr& cmdb) const
  122. {
  123. // Set the uniforms
  124. StagingGpuMemoryToken unisToken;
  125. Mat4* pmvps = static_cast<Mat4*>(stagingGpuAllocator.allocateFrame(sizeof(Mat4) * mvps.getSize() + sizeof(Vec4),
  126. StagingGpuMemoryType::UNIFORM, unisToken));
  127. if(cubeSideSize == 2.0f)
  128. {
  129. memcpy(pmvps, &mvps[0], mvps.getSizeInBytes());
  130. }
  131. else
  132. {
  133. ANKI_ASSERT(!"TODO");
  134. }
  135. Vec4* pcolor = reinterpret_cast<Vec4*>(pmvps + mvps.getSize());
  136. *pcolor = color;
  137. // Setup state
  138. ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
  139. variantInitInfo.addMutation("COLOR_TEXTURE", 0);
  140. variantInitInfo.addMutation("DITHERED_DEPTH_TEST", U32(ditherFailedDepth != 0));
  141. variantInitInfo.addConstant("INSTANCE_COUNT", mvps.getSize());
  142. const ShaderProgramResourceVariant* variant;
  143. m_prog->getOrCreateVariant(variantInitInfo, variant);
  144. cmdb->bindShaderProgram(variant->getProgram());
  145. cmdb->setVertexAttribute(0, 0, Format::R32G32B32_SFLOAT, 0);
  146. cmdb->bindVertexBuffer(0, m_cubePositionsBuffer, 0, sizeof(Vec3));
  147. cmdb->bindIndexBuffer(m_cubeIndicesBuffer, 0, IndexType::U16);
  148. cmdb->bindUniformBuffer(1, 0, unisToken.m_buffer, unisToken.m_offset, unisToken.m_range);
  149. cmdb->setLineWidth(lineSize);
  150. constexpr U INDEX_COUNT = 12 * 2;
  151. cmdb->drawElements(PrimitiveTopology::LINES, INDEX_COUNT, mvps.getSize());
  152. }
  153. void DebugDrawer2::drawLines(ConstWeakArray<Mat4> mvps, const Vec4& color, F32 lineSize, Bool ditherFailedDepth,
  154. ConstWeakArray<Vec3> linePositions, StagingGpuMemoryManager& stagingGpuAllocator,
  155. CommandBufferPtr& cmdb) const
  156. {
  157. ANKI_ASSERT(mvps.getSize() > 0);
  158. ANKI_ASSERT(linePositions.getSize() > 0 && (linePositions.getSize() % 2) == 0);
  159. // Verts
  160. StagingGpuMemoryToken vertsToken;
  161. Vec3* verts = static_cast<Vec3*>(stagingGpuAllocator.allocateFrame(sizeof(Vec3) * linePositions.getSize(),
  162. StagingGpuMemoryType::VERTEX, vertsToken));
  163. memcpy(verts, linePositions.getBegin(), linePositions.getSizeInBytes());
  164. // Set the uniforms
  165. StagingGpuMemoryToken unisToken;
  166. Mat4* pmvps = static_cast<Mat4*>(stagingGpuAllocator.allocateFrame(sizeof(Mat4) * mvps.getSize() + sizeof(Vec4),
  167. StagingGpuMemoryType::UNIFORM, unisToken));
  168. memcpy(pmvps, &mvps[0], mvps.getSizeInBytes());
  169. Vec4* pcolor = reinterpret_cast<Vec4*>(pmvps + mvps.getSize());
  170. *pcolor = color;
  171. // Setup state
  172. ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
  173. variantInitInfo.addMutation("COLOR_TEXTURE", 0);
  174. variantInitInfo.addMutation("DITHERED_DEPTH_TEST", U32(ditherFailedDepth != 0));
  175. variantInitInfo.addConstant("INSTANCE_COUNT", mvps.getSize());
  176. const ShaderProgramResourceVariant* variant;
  177. m_prog->getOrCreateVariant(variantInitInfo, variant);
  178. cmdb->bindShaderProgram(variant->getProgram());
  179. cmdb->setVertexAttribute(0, 0, Format::R32G32B32_SFLOAT, 0);
  180. cmdb->bindVertexBuffer(0, vertsToken.m_buffer, vertsToken.m_offset, sizeof(Vec3));
  181. cmdb->bindUniformBuffer(1, 0, unisToken.m_buffer, unisToken.m_offset, unisToken.m_range);
  182. cmdb->setLineWidth(lineSize);
  183. cmdb->drawArrays(PrimitiveTopology::LINES, linePositions.getSize(), mvps.getSize());
  184. }
  185. void DebugDrawer2::drawBillboardTextures(const Mat4& projMat, const Mat4& viewMat, ConstWeakArray<Vec3> positions,
  186. const Vec4& color, Bool ditherFailedDepth, TextureViewPtr tex,
  187. SamplerPtr sampler, Vec2 billboardSize,
  188. StagingGpuMemoryManager& stagingGpuAllocator, CommandBufferPtr& cmdb) const
  189. {
  190. StagingGpuMemoryToken positionsToken;
  191. Vec3* verts = static_cast<Vec3*>(
  192. stagingGpuAllocator.allocateFrame(sizeof(Vec3) * 4, StagingGpuMemoryType::VERTEX, positionsToken));
  193. verts[0] = Vec3(-0.5f, -0.5f, 0.0f);
  194. verts[1] = Vec3(+0.5f, -0.5f, 0.0f);
  195. verts[2] = Vec3(-0.5f, +0.5f, 0.0f);
  196. verts[3] = Vec3(+0.5f, +0.5f, 0.0f);
  197. StagingGpuMemoryToken uvsToken;
  198. Vec2* uvs =
  199. static_cast<Vec2*>(stagingGpuAllocator.allocateFrame(sizeof(Vec2) * 4, StagingGpuMemoryType::VERTEX, uvsToken));
  200. uvs[0] = Vec2(0.0f, 0.0f);
  201. uvs[1] = Vec2(1.0f, 0.0f);
  202. uvs[2] = Vec2(0.0f, 1.0f);
  203. uvs[3] = Vec2(1.0f, 1.0f);
  204. // Set the uniforms
  205. StagingGpuMemoryToken unisToken;
  206. Mat4* pmvps = static_cast<Mat4*>(stagingGpuAllocator.allocateFrame(
  207. sizeof(Mat4) * positions.getSize() + sizeof(Vec4), StagingGpuMemoryType::UNIFORM, unisToken));
  208. const Mat4 camTrf = viewMat.getInverse();
  209. const Vec3 zAxis = camTrf.getZAxis().xyz().getNormalized();
  210. Vec3 yAxis = Vec3(0.0f, 1.0f, 0.0f);
  211. const Vec3 xAxis = yAxis.cross(zAxis).getNormalized();
  212. yAxis = zAxis.cross(xAxis).getNormalized();
  213. Mat3 rot;
  214. rot.setColumns(xAxis, yAxis, zAxis);
  215. for(const Vec3& pos : positions)
  216. {
  217. Mat3 scale = Mat3::getIdentity();
  218. scale(0, 0) *= billboardSize.x();
  219. scale(1, 1) *= billboardSize.y();
  220. *pmvps = projMat * viewMat * Mat4(pos.xyz1(), rot * scale, 1.0f);
  221. ++pmvps;
  222. }
  223. Vec4* pcolor = reinterpret_cast<Vec4*>(pmvps);
  224. *pcolor = color;
  225. // Setup state
  226. ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
  227. variantInitInfo.addMutation("COLOR_TEXTURE", 1);
  228. variantInitInfo.addMutation("DITHERED_DEPTH_TEST", U32(ditherFailedDepth != 0));
  229. variantInitInfo.addConstant("INSTANCE_COUNT", positions.getSize());
  230. const ShaderProgramResourceVariant* variant;
  231. m_prog->getOrCreateVariant(variantInitInfo, variant);
  232. cmdb->bindShaderProgram(variant->getProgram());
  233. cmdb->setVertexAttribute(0, 0, Format::R32G32B32_SFLOAT, 0);
  234. cmdb->setVertexAttribute(1, 1, Format::R32G32_SFLOAT, 0);
  235. cmdb->bindVertexBuffer(0, positionsToken.m_buffer, positionsToken.m_offset, sizeof(Vec3));
  236. cmdb->bindVertexBuffer(1, uvsToken.m_buffer, uvsToken.m_offset, sizeof(Vec2));
  237. cmdb->bindUniformBuffer(1, 0, unisToken.m_buffer, unisToken.m_offset, unisToken.m_range);
  238. cmdb->bindSampler(1, 1, sampler);
  239. cmdb->bindTexture(1, 2, tex);
  240. cmdb->drawArrays(PrimitiveTopology::TRIANGLE_STRIP, 4, positions.getSize());
  241. }
  242. void PhysicsDebugDrawer::drawLines(const Vec3* lines, const U32 vertCount, const Vec4& color)
  243. {
  244. if(color != m_currentColor)
  245. {
  246. // Color have changed, flush and change the color
  247. flush();
  248. m_currentColor = color;
  249. }
  250. for(U32 i = 0; i < vertCount; ++i)
  251. {
  252. if(m_vertCount == m_vertCache.getSize())
  253. {
  254. flush();
  255. }
  256. m_vertCache[m_vertCount++] = lines[i];
  257. }
  258. }
  259. void PhysicsDebugDrawer::flush()
  260. {
  261. if(m_vertCount > 0)
  262. {
  263. m_dbg->drawLines(ConstWeakArray<Mat4>(&m_mvp, 1), m_currentColor, 2.0f, false,
  264. ConstWeakArray<Vec3>(&m_vertCache[0], m_vertCount), *m_stagingGpuAllocator, m_cmdb);
  265. m_vertCount = 0;
  266. }
  267. }
  268. } // end namespace anki