2
0

PhysicsDebugDrawer.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #include "PhysicsDebugDrawer.h"
  2. namespace gameplay
  3. {
  4. // The initial capacity of the debug drawer's vertex batch.
  5. #define INITIAL_CAPACITY 280
  6. PhysicsDebugDrawer::PhysicsDebugDrawer()
  7. : _mode(btIDebugDraw::DBG_DrawAabb | btIDebugDraw::DBG_DrawConstraintLimits | btIDebugDraw::DBG_DrawConstraints |
  8. btIDebugDraw::DBG_DrawContactPoints | btIDebugDraw::DBG_DrawWireframe), _program(0), _positionAttrib(0),
  9. _colorAttrib(0), _viewProjectionMatrixUniform(0), _viewProjection(NULL), _vertexData(NULL), _vertexCount(0), _vertexDataSize(0)
  10. {
  11. // Unused
  12. }
  13. PhysicsDebugDrawer::~PhysicsDebugDrawer()
  14. {
  15. SAFE_DELETE_ARRAY(_vertexData);
  16. }
  17. void PhysicsDebugDrawer::begin(const Matrix& viewProjection)
  18. {
  19. _viewProjection = &viewProjection;
  20. _vertexCount = 0;
  21. }
  22. void PhysicsDebugDrawer::end()
  23. {
  24. // Lazy load the shader program for drawing.
  25. if (!_program)
  26. {
  27. // Vertex shader for drawing colored lines.
  28. const char* vs_str = {
  29. "uniform mat4 u_viewProjectionMatrix;\n"
  30. "attribute vec4 a_position;\n"
  31. "attribute vec4 a_color;\n"
  32. "varying vec4 v_color;\n"
  33. "void main(void) {\n"
  34. " v_color = a_color;\n"
  35. " gl_Position = u_viewProjectionMatrix * a_position;\n"
  36. "}"
  37. };
  38. // Fragment shader for drawing colored lines.
  39. const char* fs_str = {
  40. #ifdef OPENGL_ES
  41. "precision highp float;\n"
  42. #endif
  43. "varying vec4 v_color;\n"
  44. "void main(void) {\n"
  45. " gl_FragColor = v_color;"
  46. "}"
  47. };
  48. // Load the vertex shader.
  49. GLuint vs;
  50. GL_ASSERT( vs = glCreateShader(GL_VERTEX_SHADER) );
  51. GLint shader_str_len = strlen(vs_str);
  52. GL_ASSERT( glShaderSource(vs, 1, &vs_str, &shader_str_len) );
  53. GL_ASSERT( glCompileShader(vs) );
  54. GLint status;
  55. GL_ASSERT( glGetShaderiv(vs, GL_COMPILE_STATUS, &status) );
  56. if (status == GL_FALSE)
  57. {
  58. GLchar errorMessage[512];
  59. GL_ASSERT( glGetShaderInfoLog(vs, sizeof(errorMessage), 0, errorMessage) );
  60. WARN_VARG("Physics debug drawing will not work; vertex shader failed to compile with error: '%s'", errorMessage);
  61. return;
  62. }
  63. // Load the fragment shader.
  64. GLuint fs;
  65. GL_ASSERT( fs = glCreateShader(GL_FRAGMENT_SHADER) );
  66. shader_str_len = strlen(fs_str);
  67. GL_ASSERT( glShaderSource(fs, 1, &fs_str, &shader_str_len) );
  68. GL_ASSERT( glCompileShader(fs) );
  69. GL_ASSERT( glGetShaderiv(fs, GL_COMPILE_STATUS, &status) );
  70. if (status == GL_FALSE)
  71. {
  72. GLchar errorMessage[512];
  73. GL_ASSERT( glGetShaderInfoLog(fs, sizeof(errorMessage), 0, errorMessage) );
  74. WARN_VARG("Physics debug drawing will not work; fragment shader failed to compile with error: '%s'", errorMessage);
  75. return;
  76. }
  77. // Create the shader program and link it.
  78. GL_ASSERT( _program = glCreateProgram() );
  79. GL_ASSERT( glAttachShader(_program, vs) );
  80. GL_ASSERT( glAttachShader(_program, fs) );
  81. GL_ASSERT( glLinkProgram(_program) );
  82. GL_ASSERT( glGetProgramiv(_program, GL_LINK_STATUS, &status) );
  83. if (status == GL_FALSE)
  84. {
  85. GLchar errorMessage[512];
  86. GL_ASSERT( glGetProgramInfoLog(_program, sizeof(errorMessage), 0, errorMessage) );
  87. WARN_VARG("Physics debug drawing will not work; shader program failed to link with error: '%s'", errorMessage);
  88. return;
  89. }
  90. // Get the attribute and uniform locations.
  91. GL_ASSERT( glUseProgram(_program) );
  92. GL_ASSERT( _positionAttrib = glGetAttribLocation(_program, "a_position") );
  93. GL_ASSERT( _colorAttrib = glGetAttribLocation(_program, "a_color") );
  94. GL_ASSERT( _viewProjectionMatrixUniform = glGetUniformLocation(_program, "u_viewProjectionMatrix") );
  95. }
  96. // Set the shader program and vertex attributes.
  97. GL_ASSERT( glUseProgram(_program) );
  98. GL_ASSERT( glEnableVertexAttribArray(_positionAttrib) );
  99. GL_ASSERT( glEnableVertexAttribArray(_colorAttrib) );
  100. GL_ASSERT( glVertexAttribPointer(_positionAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, _vertexData) );
  101. GL_ASSERT( glVertexAttribPointer(_colorAttrib, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 7, &_vertexData[3]) );
  102. // Set the camera's view projection matrix and draw.
  103. GL_ASSERT( glUniformMatrix4fv(_viewProjectionMatrixUniform, 1, GL_FALSE, _viewProjection->m) );
  104. GL_ASSERT( glDrawArrays(GL_LINES, 0, _vertexCount / 7) );
  105. // Reset shader state.
  106. GL_ASSERT( glDisableVertexAttribArray(_positionAttrib) );
  107. GL_ASSERT( glDisableVertexAttribArray(_colorAttrib) );
  108. GL_ASSERT( glUseProgram(0) );
  109. }
  110. void PhysicsDebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
  111. {
  112. // Allocate extra space in the vertex data batch if it is needed.
  113. if (_vertexDataSize - _vertexCount < 14)
  114. {
  115. if (_vertexDataSize > 0)
  116. {
  117. unsigned int newVertexDataSize = _vertexDataSize * 2;
  118. float* newVertexData = new float[newVertexDataSize];
  119. memcpy(newVertexData, _vertexData, _vertexDataSize * sizeof(float));
  120. SAFE_DELETE_ARRAY(_vertexData);
  121. _vertexData = newVertexData;
  122. _vertexDataSize = newVertexDataSize;
  123. }
  124. else
  125. {
  126. _vertexDataSize = INITIAL_CAPACITY;
  127. _vertexData = new float[_vertexDataSize];
  128. }
  129. }
  130. // Create the vertex data for the line and copy it into the batch.
  131. float vertexData[] = {
  132. from.getX(), from.getY(), from.getZ(),
  133. fromColor.getX(), fromColor.getY(), fromColor.getZ(), 1.0f,
  134. to.getX(), to.getY(), to.getZ(),
  135. toColor.getX(), toColor.getY(), toColor.getZ(), 1.0f
  136. };
  137. memcpy(&_vertexData[_vertexCount], vertexData, sizeof(float) * 14);
  138. _vertexCount += 14;
  139. }
  140. void PhysicsDebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
  141. {
  142. drawLine(from, to, color, color);
  143. }
  144. void PhysicsDebugDrawer::drawContactPoint(const btVector3& pointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
  145. {
  146. drawLine(pointOnB, pointOnB + normalOnB, color);
  147. }
  148. void PhysicsDebugDrawer::reportErrorWarning(const char* warningString)
  149. {
  150. WARN(warningString);
  151. }
  152. void PhysicsDebugDrawer::draw3dText(const btVector3& location, const char* textString)
  153. {
  154. WARN("Physics debug drawing: 3D text is not supported.");
  155. }
  156. void PhysicsDebugDrawer::setDebugMode(int mode)
  157. {
  158. _mode = mode;
  159. }
  160. int PhysicsDebugDrawer::getDebugMode() const
  161. {
  162. return _mode;
  163. }
  164. }