DebugRenderer.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "AnimatedModel.h"
  25. #include "DebugRenderer.h"
  26. #include "Exception.h"
  27. #include "Light.h"
  28. #include "Log.h"
  29. #include "PixelShader.h"
  30. #include "Profiler.h"
  31. #include "Renderer.h"
  32. #include "RendererEvents.h"
  33. #include "RendererImpl.h"
  34. #include "ResourceCache.h"
  35. #include "VertexShader.h"
  36. #include "DebugNew.h"
  37. DebugRenderer::DebugRenderer(Renderer* renderer, ResourceCache* cache) :
  38. mRenderer(renderer),
  39. mCache(cache)
  40. {
  41. if (!mRenderer)
  42. EXCEPTION("Null renderer for DebugRenderer");
  43. mDebugVS = mCache->getResource<VertexShader>("Shaders/SM2/Basic_VCol.vs2");
  44. mDebugPS = mCache->getResource<PixelShader>("Shaders/SM2/Basic_VCol.ps2");
  45. subscribeToEvent(EVENT_ENDFRAME, EVENT_HANDLER(DebugRenderer, handleEndFrame));
  46. }
  47. DebugRenderer::~DebugRenderer()
  48. {
  49. }
  50. void DebugRenderer::render(Camera* camera)
  51. {
  52. if ((!camera) || ((!mLines.size()) && (!mNoDepthLines.size())))
  53. return;
  54. PROFILE(DebugGeometry_Render);
  55. mRenderer->setAlphaTest(false);
  56. mRenderer->setBlendMode(BLEND_REPLACE);
  57. mRenderer->setColorWrite(true);
  58. mRenderer->setCullMode(CULL_NONE);
  59. mRenderer->setDepthWrite(true);
  60. mRenderer->setDepthTest(CMP_LESSEQUAL);
  61. mRenderer->setFillMode(FILL_SOLID);
  62. mRenderer->setScissorTest(false);
  63. mRenderer->setStencilTest(false);
  64. mRenderer->setVertexShader(mDebugVS);
  65. mRenderer->setPixelShader(mDebugPS);
  66. mRenderer->setVertexShaderConstant(getVSRegister(VSP_MODELVIEWPROJ), camera->getProjection() * camera->getInverseWorldTransform());
  67. mRenderer->setPixelShaderConstant(getPSRegister(PSP_MATDIFFCOLOR), Color(1.0f, 1.0f, 1.0f, 1.0f));
  68. // Draw all line geometry with depth testing
  69. if (mLines.size())
  70. {
  71. mRenderer->beginImmediate(LINE_LIST, mLines.size() * 2, MASK_POSITION | MASK_COLOR);
  72. float* dest = (float*)mRenderer->getImmediateDataPtr();
  73. for (unsigned i = 0; i < mLines.size(); ++i)
  74. {
  75. const DebugLine& line = mLines[i];
  76. *dest++ = line.mStart.mX; *dest++ = line.mStart.mY; *dest++ = line.mStart.mZ;
  77. *((unsigned*)dest) = line.mColor; dest++;
  78. *dest++ = line.mEnd.mX; *dest++ = line.mEnd.mY; *dest++ = line.mEnd.mZ;
  79. *((unsigned*)dest) = line.mColor; dest++;
  80. }
  81. mRenderer->endImmediate();
  82. }
  83. // Draw all line geometry without depth testing
  84. mRenderer->setDepthTest(CMP_ALWAYS);
  85. if (mNoDepthLines.size())
  86. {
  87. mRenderer->beginImmediate(LINE_LIST, mNoDepthLines.size() * 2, MASK_POSITION | MASK_COLOR);
  88. float* dest = (float*)mRenderer->getImmediateDataPtr();
  89. for (unsigned i = 0; i < mNoDepthLines.size(); ++i)
  90. {
  91. const DebugLine& line = mNoDepthLines[i];
  92. *dest++ = line.mStart.mX; *dest++ = line.mStart.mY; *dest++ = line.mStart.mZ;
  93. *((unsigned*)dest) = line.mColor; dest++;
  94. *dest++ = line.mEnd.mX; *dest++ = line.mEnd.mY; *dest++ = line.mEnd.mZ;
  95. *((unsigned*)dest) = line.mColor; dest++;
  96. }
  97. mRenderer->endImmediate();
  98. }
  99. }
  100. void DebugRenderer::addLine(const Vector3& start, const Vector3& end, const Color& color, bool depthTest)
  101. {
  102. if (depthTest)
  103. mLines.push_back(DebugLine(start, end, getD3DColor(color)));
  104. else
  105. mNoDepthLines.push_back(DebugLine(start, end, getD3DColor(color)));
  106. }
  107. void DebugRenderer::addBoundingBox(const BoundingBox& box, const Color& color, bool depthTest)
  108. {
  109. const Vector3& min = box.mMin;
  110. const Vector3& max = box.mMax;
  111. Vector3 v0(max.mX, min.mY, min.mZ);
  112. Vector3 v1(max.mX, max.mY, min.mZ);
  113. Vector3 v2(min.mX, max.mY, min.mZ);
  114. Vector3 v3(min.mX, min.mY, max.mZ);
  115. Vector3 v4(max.mX, min.mY, max.mZ);
  116. Vector3 v5(min.mX, max.mY, max.mZ);
  117. unsigned d3dColor = getD3DColor(color);
  118. std::vector<DebugLine>* dest = &mLines;
  119. if (!depthTest)
  120. dest = &mNoDepthLines;
  121. dest->push_back(DebugLine(min, v0, d3dColor));
  122. dest->push_back(DebugLine(v0, v1, d3dColor));
  123. dest->push_back(DebugLine(v1, v2, d3dColor));
  124. dest->push_back(DebugLine(v2, min, d3dColor));
  125. dest->push_back(DebugLine(v3, v4, d3dColor));
  126. dest->push_back(DebugLine(v4, max, d3dColor));
  127. dest->push_back(DebugLine(max, v5, d3dColor));
  128. dest->push_back(DebugLine(v5, v3, d3dColor));
  129. dest->push_back(DebugLine(min, v3, d3dColor));
  130. dest->push_back(DebugLine(v0, v4, d3dColor));
  131. dest->push_back(DebugLine(v1, max, d3dColor));
  132. dest->push_back(DebugLine(v2, v5, d3dColor));
  133. }
  134. void DebugRenderer::addBoundingBox(const BoundingBox& box, const Matrix4x3& transform, const Color& color, bool depthTest)
  135. {
  136. const Vector3& min = box.mMin;
  137. const Vector3& max = box.mMax;
  138. Vector3 v0(transform * Vector3(min.mX, min.mY, min.mZ));
  139. Vector3 v1(transform * Vector3(max.mX, min.mY, min.mZ));
  140. Vector3 v2(transform * Vector3(max.mX, max.mY, min.mZ));
  141. Vector3 v3(transform * Vector3(min.mX, max.mY, min.mZ));
  142. Vector3 v4(transform * Vector3(min.mX, min.mY, max.mZ));
  143. Vector3 v5(transform * Vector3(max.mX, min.mY, max.mZ));
  144. Vector3 v6(transform * Vector3(max.mX, max.mY, max.mZ));
  145. Vector3 v7(transform * Vector3(min.mX, max.mY, max.mZ));
  146. unsigned d3dColor = getD3DColor(color);
  147. std::vector<DebugLine>* dest = &mLines;
  148. if (!depthTest)
  149. dest = &mNoDepthLines;
  150. dest->push_back(DebugLine(v0, v1, d3dColor));
  151. dest->push_back(DebugLine(v1, v2, d3dColor));
  152. dest->push_back(DebugLine(v2, v3, d3dColor));
  153. dest->push_back(DebugLine(v3, v0, d3dColor));
  154. dest->push_back(DebugLine(v4, v5, d3dColor));
  155. dest->push_back(DebugLine(v5, v6, d3dColor));
  156. dest->push_back(DebugLine(v6, v7, d3dColor));
  157. dest->push_back(DebugLine(v7, v4, d3dColor));
  158. dest->push_back(DebugLine(v0, v4, d3dColor));
  159. dest->push_back(DebugLine(v1, v5, d3dColor));
  160. dest->push_back(DebugLine(v2, v6, d3dColor));
  161. dest->push_back(DebugLine(v3, v7, d3dColor));
  162. }
  163. void DebugRenderer::addFrustum(const Frustum& frustum, const Color& color, bool depthTest)
  164. {
  165. const Vector3* vertices = frustum.getVertices();
  166. unsigned d3dColor = getD3DColor(color);
  167. std::vector<DebugLine>* dest = &mLines;
  168. if (!depthTest)
  169. dest = &mNoDepthLines;
  170. dest->push_back(DebugLine(vertices[0], vertices[1], d3dColor));
  171. dest->push_back(DebugLine(vertices[1], vertices[2], d3dColor));
  172. dest->push_back(DebugLine(vertices[2], vertices[3], d3dColor));
  173. dest->push_back(DebugLine(vertices[3], vertices[0], d3dColor));
  174. dest->push_back(DebugLine(vertices[4], vertices[5], d3dColor));
  175. dest->push_back(DebugLine(vertices[5], vertices[6], d3dColor));
  176. dest->push_back(DebugLine(vertices[6], vertices[7], d3dColor));
  177. dest->push_back(DebugLine(vertices[7], vertices[4], d3dColor));
  178. dest->push_back(DebugLine(vertices[0], vertices[4], d3dColor));
  179. dest->push_back(DebugLine(vertices[1], vertices[5], d3dColor));
  180. dest->push_back(DebugLine(vertices[2], vertices[6], d3dColor));
  181. dest->push_back(DebugLine(vertices[3], vertices[7], d3dColor));
  182. }
  183. void DebugRenderer::addSkeleton(const Skeleton& skeleton, const Color& color, bool depthTest)
  184. {
  185. const std::vector<SharedPtr<Bone> >& bones = skeleton.getBones();
  186. if (!bones.size())
  187. return;
  188. DebugLine newLine;
  189. newLine.mColor = getD3DColor(color);
  190. std::vector<DebugLine>* dest = &mLines;
  191. if (!depthTest)
  192. dest = &mNoDepthLines;
  193. for (unsigned i = 0; i < bones.size(); ++i)
  194. {
  195. Bone* bone = bones[i];
  196. Node* parent = bone->getParent();
  197. if ((parent->getNodeFlags() & NODE_BONE) == 0)
  198. parent = 0;
  199. newLine.mStart = bone->getWorldPosition();
  200. // If bone has a parent defined, draw a line to it. Else draw the bone as a point
  201. if (parent)
  202. newLine.mEnd = parent->getWorldPosition();
  203. else
  204. newLine.mEnd = newLine.mStart;
  205. dest->push_back(newLine);
  206. }
  207. }
  208. void DebugRenderer::handleEndFrame(StringHash eventType, VariantMap& eventData)
  209. {
  210. mLines.clear();
  211. mNoDepthLines.clear();
  212. }