Box2DDebugDraw.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include "Box2DDebugDraw.h"
  2. #include "core/VideoDriver.h"
  3. #include "RenderState.h"
  4. #include "core/gl/VideoDriverGLES20.h"
  5. Box2DDraw::Box2DDraw(): _worldScale(1.0f), _world(0)
  6. {
  7. m_drawFlags = 0xffffffff;
  8. const char* vertexShaderData = "\
  9. uniform mediump mat4 projection;\
  10. attribute vec2 a_position;\
  11. void main() {\
  12. vec4 position = vec4(a_position, 0.0, 1.0);\
  13. gl_Position = projection * position;\
  14. }\
  15. ";
  16. const char* fragmentShaderData = "\
  17. uniform mediump vec4 color;\
  18. void main() { \
  19. gl_FragColor = color; \
  20. } \
  21. ";
  22. _program = new ShaderProgramGL();
  23. int vs = ShaderProgramGL::createShader(GL_VERTEX_SHADER, vertexShaderData, 0, 0);
  24. int fs = ShaderProgramGL::createShader(GL_FRAGMENT_SHADER, fragmentShaderData, 0, 0);
  25. int pr = ShaderProgramGL::createProgram(vs, fs, (VertexDeclarationGL*)IVideoDriver::instance->getVertexDeclaration(VERTEX_POSITION));
  26. _program->init(pr);
  27. }
  28. Box2DDraw::~Box2DDraw()
  29. {
  30. delete _program;
  31. }
  32. void Box2DDraw::doRender(const RenderState &rs)
  33. {
  34. rs.renderer->drawBatch();
  35. _world->SetDebugDraw(this);
  36. _program->bind();
  37. Matrix m = Matrix(rs.transform) * rs.renderer->getView() * rs.renderer->getProjection();
  38. _program->setUniform("projection", &m);
  39. glEnable(GL_BLEND);
  40. glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  41. _world->DrawDebugData();
  42. _world->SetDebugDraw(0);
  43. rs.renderer->getDriver()->setDefaultSettings();
  44. }
  45. void Box2DDraw::DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
  46. {
  47. createPolygonVertices(vertices, vertexCount);
  48. drawPrimitives(false, true, vertexCount, color);
  49. }
  50. /// Draw a solid closed polygon provided in CCW order.
  51. void Box2DDraw::DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
  52. {
  53. createPolygonVertices(vertices, vertexCount);
  54. drawPrimitives(true, true, vertexCount, color);
  55. }
  56. /// Draw a circle.
  57. void Box2DDraw::DrawCircle(const b2Vec2& center, float32 aRadius, const b2Color& color)
  58. {
  59. createCircleVertices(center, aRadius);
  60. drawPrimitives(false, true, CIRCLE_SEGMENTS, color);
  61. }
  62. /// Draw a solid circle.
  63. void Box2DDraw::DrawSolidCircle(const b2Vec2& center, float32 aRadius, const b2Vec2& aAxis,
  64. const b2Color& color)
  65. {
  66. createCircleVertices(center, aRadius);
  67. drawPrimitives(true, true, CIRCLE_SEGMENTS, color);
  68. // Draw the axis line
  69. DrawSegment(center, center + aRadius * aAxis, color);
  70. }
  71. /// Draw a line segment.
  72. void Box2DDraw::DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color)
  73. {
  74. mVertices[0].x = p1.x * _worldScale;
  75. mVertices[0].y = p1.y * _worldScale;
  76. mVertices[1].x = p2.x * _worldScale;
  77. mVertices[1].y = p2.y * _worldScale;
  78. drawPrimitives(false, true, 2, color);
  79. }
  80. /// Draw a transform. Choose your own length scale.
  81. /// @param xf a transform.
  82. void Box2DDraw::DrawTransform(const b2Transform& xf)
  83. {
  84. b2Vec2 p1 = xf.p, p2;
  85. const float32 k_axisScale = 0.4f;
  86. p2 = p1 + k_axisScale * xf.q.GetXAxis();
  87. DrawSegment(p1, p2, b2Color(1, 0, 0));
  88. p2 = p1 + k_axisScale * xf.q.GetYAxis();
  89. DrawSegment(p1, p2, b2Color(0, 1, 0));
  90. }
  91. void Box2DDraw::createCircleVertices(const b2Vec2& center, float32 aRadius)
  92. {
  93. int vertexCount = 16;
  94. const float32 k_increment = 2.0f * b2_pi / CIRCLE_SEGMENTS;
  95. float32 theta = 0.0f;
  96. for (int32 i = 0; i < CIRCLE_SEGMENTS; ++i)
  97. {
  98. b2Vec2 v = center + aRadius * b2Vec2(scalar::cos(theta), scalar::sin(theta));
  99. mVertices[i].x = _worldScale * v.x;
  100. mVertices[i].y = _worldScale * v.y;
  101. theta += k_increment;
  102. }
  103. }
  104. void Box2DDraw::createPolygonVertices(const b2Vec2* vertices, int32 vertexCount)
  105. {
  106. if (vertexCount > MAX_VERTICES)
  107. {
  108. log::warning("need more vertices");
  109. return;
  110. }
  111. // convert vertices to screen resolution
  112. for (int i = 0; i < vertexCount; i++)
  113. {
  114. mVertices[i].x= _worldScale * vertices[i].x;
  115. mVertices[i].y = _worldScale * vertices[i].y;
  116. }
  117. }
  118. //------------------------------------------------------------------------
  119. void Box2DDraw::drawPrimitives(bool drawTriangles, bool drawLines, int count, const b2Color& color)
  120. {
  121. glEnableVertexAttribArray(0);
  122. glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (GLfloat*) mVertices);
  123. if (drawTriangles)
  124. {
  125. Vector4 c(color.r, color.g, color.b, 0.5f);
  126. _program->setUniform("color", &c, 1);
  127. glDrawArrays(GL_TRIANGLE_FAN, 0, count);
  128. }
  129. if (drawLines)
  130. {
  131. Vector4 c(color.r, color.g, color.b, 1.0f);
  132. _program->setUniform("color", &c, 1);
  133. glDrawArrays(GL_LINE_LOOP, 0, count);
  134. }
  135. glDisableVertexAttribArray(0);
  136. }