DebugDrawer.cpp 11 KB

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