debug_line.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "debug_line.h"
  6. #include "math_utils.h"
  7. #include "color4.h"
  8. #include "vector3.h"
  9. #include "matrix4x4.h"
  10. #include "error.h"
  11. #include <string.h> // memcpy
  12. #include <bgfx/bgfx.h>
  13. namespace crown
  14. {
  15. namespace debug_line
  16. {
  17. #if CROWN_PLATFORM_LINUX || CROWN_PLATFORM_ANDROID
  18. static const uint8_t vs_h[325] =
  19. {
  20. 0x56, 0x53, 0x48, 0x04, 0xa4, 0x8b, 0xef, 0x49, 0x01, 0x00, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // VSH....I...u_mod
  21. 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, // elViewProj......
  22. 0x20, 0x01, 0x00, 0x00, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x68, 0x69, // ...attribute hi
  23. 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, // ghp vec4 a_color
  24. 0x30, 0x3b, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x68, 0x69, 0x67, // 0;.attribute hig
  25. 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, // hp vec3 a_positi
  26. 0x6f, 0x6e, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x69, 0x67, 0x68, // on;.varying high
  27. 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, // p vec4 v_color0;
  28. 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x6d, // .uniform highp m
  29. 0x61, 0x74, 0x34, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, // at4 u_modelViewP
  30. 0x72, 0x6f, 0x6a, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x28, // roj;.void main (
  31. 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, // ).{. highp vec4
  32. 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, // tmpvar_1;. tmp
  33. 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, // var_1.w = 1.0;.
  34. 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, // tmpvar_1.xyz =
  35. 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, // a_position;. gl
  36. 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x75, 0x5f, 0x6d, // _Position = (u_m
  37. 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, // odelViewProj * t
  38. 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x63, 0x6f, // mpvar_1);. v_co
  39. 0x6c, 0x6f, 0x72, 0x30, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, // lor0 = a_color0;
  40. 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // .}...
  41. };
  42. static const uint8_t fs_h[89] =
  43. {
  44. 0x46, 0x53, 0x48, 0x04, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x76, 0x61, // FSH....I..J...va
  45. 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, // rying highp vec4
  46. 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, // v_color0;.void
  47. 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, // main ().{. gl_F
  48. 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, // ragColor = v_col
  49. 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // or0;.}...
  50. };
  51. #elif CROWN_PLATFORM_WINDOWS
  52. static const uint8_t vs_h[419] =
  53. {
  54. 0x56, 0x53, 0x48, 0x03, 0xa4, 0x8b, 0xef, 0x49, 0x01, 0x00, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, // VSH....I...u_mod
  55. 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x09, 0x01, 0x00, 0x00, 0x04, 0x00, // elViewProj......
  56. 0x80, 0x01, 0x00, 0x03, 0xfe, 0xff, 0xfe, 0xff, 0x23, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, // ........#.CTAB..
  57. 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, // ..W.............
  58. 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, // ......P...0.....
  59. 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, // [email protected]_
  60. 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0x03, 0x00, // modelViewProj...
  61. 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x73, // ..............vs
  62. 0x5f, 0x33, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, // _3_0.Microsoft (
  63. 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, // R) HLSL Shader C
  64. 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, // ompiler 9.29.952
  65. 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, 0x05, 0x04, 0x00, 0x0f, 0xa0, 0x00, 0x00, // .3111.Q.........
  66. 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, // .?..............
  67. 0x00, 0x02, 0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, // ................
  68. 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, // ................
  69. 0x0f, 0xe0, 0x1f, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0xe0, 0x05, 0x00, // ................
  70. 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x90, 0x05, 0x00, // ................
  71. 0x00, 0x03, 0x01, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x55, 0x90, 0x02, 0x00, // ............U...
  72. 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x05, 0x00, // ................
  73. 0x00, 0x03, 0x01, 0x00, 0x0f, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0xaa, 0x90, 0x02, 0x00, // ................
  74. 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x01, 0x00, // ................
  75. 0x00, 0x02, 0x01, 0x00, 0x0f, 0x80, 0x03, 0x00, 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, // ................
  76. 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x04, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, // ................
  77. 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, // ................
  78. 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x90, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, // ................
  79. 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x0f, 0xe0, 0x01, 0x00, 0xe4, 0x80, 0xff, 0xff, // ................
  80. 0x00, 0x00, 0x00, // ...
  81. };
  82. static const uint8_t fs_h[137] =
  83. {
  84. 0x46, 0x53, 0x48, 0x03, 0xa4, 0x8b, 0xef, 0x49, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x03, 0xff, 0xff, // FSH....I..|.....
  85. 0xfe, 0xff, 0x16, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, // ....CTAB....#...
  86. 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, // ................
  87. 0x1c, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x33, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, // ....ps_3_0.Micro
  88. 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, // soft (R) HLSL Sh
  89. 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, // ader Compiler 9.
  90. 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x1f, 0x00, 0x00, 0x02, // 29.952.3111.....
  91. 0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x0f, 0x80, // ................
  92. 0x00, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00, 0x00, // .........
  93. };
  94. #endif
  95. static bgfx::VertexDecl s_decl;
  96. static bgfx::ProgramHandle s_prog;
  97. void init()
  98. {
  99. s_decl
  100. .begin()
  101. .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
  102. .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
  103. .end();
  104. bgfx::ShaderHandle vs = bgfx::createShader(bgfx::makeRef(vs_h, sizeof(vs_h)));
  105. CE_ASSERT(bgfx::isValid(vs), "Failed to create vertex shader");
  106. bgfx::ShaderHandle fs = bgfx::createShader(bgfx::makeRef(fs_h, sizeof(fs_h)));
  107. CE_ASSERT(bgfx::isValid(fs), "Failed to create fragment shader");
  108. s_prog = bgfx::createProgram(vs, fs, true);
  109. CE_ASSERT(bgfx::isValid(s_prog), "Failed to create program");
  110. }
  111. void shutdown()
  112. {
  113. bgfx::destroyProgram(s_prog);
  114. }
  115. } // namespace debug_line
  116. DebugLine::DebugLine(bool depth_test)
  117. : _depth_test(depth_test)
  118. , _num(0)
  119. {
  120. }
  121. void DebugLine::add_line(const Vector3& start, const Vector3& end, const Color4& color)
  122. {
  123. if (_num >= CROWN_MAX_DEBUG_LINES)
  124. return;
  125. _lines[_num].p0[0] = start.x;
  126. _lines[_num].p0[1] = start.y;
  127. _lines[_num].p0[2] = start.z;
  128. _lines[_num].c0 = to_abgr(color);
  129. _lines[_num].p1[0] = end.x;
  130. _lines[_num].p1[1] = end.y;
  131. _lines[_num].p1[2] = end.z;
  132. _lines[_num].c1 = to_abgr(color);
  133. _num++;
  134. }
  135. void DebugLine::add_axes(const Matrix4x4& m, float length)
  136. {
  137. const Vector3 pos = translation(m);
  138. add_line(pos, pos + x(m)*length, COLOR4_RED);
  139. add_line(pos, pos + y(m)*length, COLOR4_GREEN);
  140. add_line(pos, pos + z(m)*length, COLOR4_BLUE);
  141. }
  142. void DebugLine::add_circle(const Vector3& center, float radius, const Vector3& normal, const Color4& color, uint32_t segments)
  143. {
  144. const Vector3 dir = normal;
  145. const Vector3 arr[] =
  146. {
  147. { dir.z, dir.z, -dir.x -dir.y },
  148. { -dir.y -dir.z, dir.x, dir.x }
  149. };
  150. const int idx = ((dir.z != 0.0f) && (-dir.x != dir.y));
  151. Vector3 right = arr[idx];
  152. normalize(right);
  153. const float incr = 360.0f / (float)(segments >= 3 ? segments : 3);
  154. float deg0 = 0.0f;
  155. for (uint32_t ss = 0; ss < segments; ++ss, deg0 += incr)
  156. {
  157. const float rad0 = to_rad(deg0);
  158. const float rad1 = to_rad(deg0 + incr);
  159. const Vector3 from0 = right*cos(-rad0) + cross(dir, right)*sin(-rad0) + dir*dot(dir, right)*(1.0f-cos(-rad0));
  160. const Vector3 from1 = right*cos(-rad1) + cross(dir, right)*sin(-rad1) + dir*dot(dir, right)*(1.0f-cos(-rad1));
  161. add_line(center + radius*from0, center + radius*from1, color);
  162. }
  163. }
  164. void DebugLine::add_cone(const Vector3& from, const Vector3& to, float radius, const Color4& color, uint32_t segments)
  165. {
  166. Vector3 dir = to - from;
  167. normalize(dir);
  168. const Vector3 arr[] =
  169. {
  170. { dir.z, dir.z, -dir.x -dir.y },
  171. { -dir.y -dir.z, dir.x, dir.x }
  172. };
  173. const int idx = ((dir.z != 0.0f) && (-dir.x != dir.y));
  174. Vector3 right = arr[idx];
  175. normalize(right);
  176. const float incr = 360.0f / (float)(segments >= 3 ? segments : 3);
  177. float deg0 = 0.0f;
  178. for (uint32_t ss = 0; ss < segments; ++ss, deg0 += incr)
  179. {
  180. const float rad0 = to_rad(deg0);
  181. const float rad1 = to_rad(deg0 + incr);
  182. const Vector3 from0 = right*cos(-rad0) + cross(dir, right)*sin(-rad0) + dir*dot(dir, right)*(1.0f-cos(-rad0));
  183. const Vector3 from1 = right*cos(-rad1) + cross(dir, right)*sin(-rad1) + dir*dot(dir, right)*(1.0f-cos(-rad1));
  184. add_line(from + radius*from0, to, color);
  185. add_line(from + radius*from0, from + radius*from1, color);
  186. }
  187. }
  188. void DebugLine::add_sphere(const Vector3& center, const float radius, const Color4& color, uint32_t segments)
  189. {
  190. add_circle(center, radius, VECTOR3_XAXIS, color, segments);
  191. add_circle(center, radius, VECTOR3_YAXIS, color, segments);
  192. add_circle(center, radius, VECTOR3_ZAXIS, color, segments);
  193. }
  194. void DebugLine::add_obb(const Matrix4x4& tm, const Vector3& half_extents, const Color4& color)
  195. {
  196. const Vector3 o = vector3(tm.t.x, tm.t.y, tm.t.z);
  197. const Vector3 x = vector3(tm.x.x, tm.x.y, tm.x.z) * half_extents.x;
  198. const Vector3 y = vector3(tm.y.x, tm.y.y, tm.y.z) * half_extents.y;
  199. const Vector3 z = vector3(tm.z.x, tm.z.y, tm.z.z) * half_extents.z;
  200. // Back face
  201. add_line(o - x - y - z, o + x - y - z, color);
  202. add_line(o + x - y - z, o + x + y - z, color);
  203. add_line(o + x + y - z, o - x + y - z, color);
  204. add_line(o - x + y - z, o - x - y - z, color);
  205. add_line(o - x - y + z, o + x - y + z, color);
  206. add_line(o + x - y + z, o + x + y + z, color);
  207. add_line(o + x + y + z, o - x + y + z, color);
  208. add_line(o - x + y + z, o - x - y + z, color);
  209. add_line(o - x - y - z, o - x - y + z, color);
  210. add_line(o + x - y - z, o + x - y + z, color);
  211. add_line(o + x + y - z, o + x + y + z, color);
  212. add_line(o - x + y - z, o - x + y + z, color);
  213. }
  214. void DebugLine::reset()
  215. {
  216. _num = 0;
  217. }
  218. void DebugLine::submit()
  219. {
  220. if (!_num)
  221. return;
  222. if (!checkAvailTransientVertexBuffer(_num * 2, debug_line::s_decl))
  223. return;
  224. bgfx::TransientVertexBuffer tvb;
  225. bgfx::allocTransientVertexBuffer(&tvb, _num * 2, debug_line::s_decl);
  226. memcpy(tvb.data, _lines, sizeof(Line) * _num);
  227. bgfx::setState(BGFX_STATE_PT_LINES
  228. | BGFX_STATE_RGB_WRITE
  229. | (_depth_test ? (BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_DEPTH_WRITE) : 0)
  230. | BGFX_STATE_CULL_CW);
  231. bgfx::setVertexBuffer(&tvb, 0, _num * 2);
  232. bgfx::submit(0, debug_line::s_prog);
  233. }
  234. } // namespace crown