Drawer.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. #include "anki/renderer/Drawer.h"
  2. #include "anki/resource/ShaderProgram.h"
  3. #include "anki/physics/Convertors.h"
  4. #include "anki/collision/Collision.h"
  5. #include "anki/scene/Frustumable.h"
  6. #include "anki/scene/Octree.h"
  7. #include "anki/resource/Material.h"
  8. #include "anki/scene/Renderable.h"
  9. #include "anki/scene/Camera.h"
  10. #include "anki/scene/ModelNode.h"
  11. namespace anki {
  12. //==============================================================================
  13. // DebugDrawer =
  14. //==============================================================================
  15. //==============================================================================
  16. DebugDrawer::DebugDrawer()
  17. {
  18. sProg.load("shaders/Dbg.glsl");
  19. positionsVbo.create(GL_ARRAY_BUFFER, sizeof(positions), NULL,
  20. GL_DYNAMIC_DRAW);
  21. colorsVbo.create(GL_ARRAY_BUFFER, sizeof(colors), NULL, GL_DYNAMIC_DRAW);
  22. vao.create();
  23. const int positionAttribLoc = 0;
  24. vao.attachArrayBufferVbo(positionsVbo, positionAttribLoc, 3, GL_FLOAT,
  25. GL_FALSE, 0, NULL);
  26. const int colorAttribLoc = 1;
  27. vao.attachArrayBufferVbo(colorsVbo, colorAttribLoc, 3, GL_FLOAT, GL_FALSE,
  28. 0, NULL);
  29. pointIndex = 0;
  30. modelMat.setIdentity();
  31. crntCol = Vec3(1.0, 0.0, 0.0);
  32. }
  33. //==============================================================================
  34. void DebugDrawer::drawLine(const Vec3& from, const Vec3& to, const Vec4& color)
  35. {
  36. setColor(color);
  37. begin();
  38. pushBackVertex(from);
  39. pushBackVertex(to);
  40. end();
  41. }
  42. //==============================================================================
  43. void DebugDrawer::drawGrid()
  44. {
  45. Vec4 col0(0.5, 0.5, 0.5, 1.0);
  46. Vec4 col1(0.0, 0.0, 1.0, 1.0);
  47. Vec4 col2(1.0, 0.0, 0.0, 1.0);
  48. const float SPACE = 1.0; // space between lines
  49. const int NUM = 57; // lines number. must be odd
  50. const float GRID_HALF_SIZE = ((NUM - 1) * SPACE / 2);
  51. setColor(col0);
  52. begin();
  53. for(int x = - NUM / 2 * SPACE; x < NUM / 2 * SPACE; x += SPACE)
  54. {
  55. setColor(col0);
  56. // if the middle line then change color
  57. if(x == 0)
  58. {
  59. setColor(col1);
  60. }
  61. // line in z
  62. pushBackVertex(Vec3(x, 0.0, -GRID_HALF_SIZE));
  63. pushBackVertex(Vec3(x, 0.0, GRID_HALF_SIZE));
  64. // if middle line change col so you can highlight the x-axis
  65. if(x == 0)
  66. {
  67. setColor(col2);
  68. }
  69. // line in the x
  70. pushBackVertex(Vec3(-GRID_HALF_SIZE, 0.0, x));
  71. pushBackVertex(Vec3(GRID_HALF_SIZE, 0.0, x));
  72. }
  73. // render
  74. end();
  75. }
  76. //==============================================================================
  77. void DebugDrawer::drawSphere(float radius, int complexity)
  78. {
  79. std::vector<Vec3>* sphereLines;
  80. // Pre-calculate the sphere points5
  81. //
  82. std::map<uint, std::vector<Vec3> >::iterator it =
  83. complexityToPreCalculatedSphere.find(complexity);
  84. if(it != complexityToPreCalculatedSphere.end()) // Found
  85. {
  86. sphereLines = &(it->second);
  87. }
  88. else // Not found
  89. {
  90. complexityToPreCalculatedSphere[complexity] = std::vector<Vec3>();
  91. sphereLines = &complexityToPreCalculatedSphere[complexity];
  92. float fi = Math::PI / complexity;
  93. Vec3 prev(1.0, 0.0, 0.0);
  94. for(float th = fi; th < Math::PI * 2.0 + fi; th += fi)
  95. {
  96. Vec3 p = Mat3(Euler(0.0, th, 0.0)) * Vec3(1.0, 0.0, 0.0);
  97. for(float th2 = 0.0; th2 < Math::PI; th2 += fi)
  98. {
  99. Mat3 rot(Euler(th2, 0.0, 0.0));
  100. Vec3 rotPrev = rot * prev;
  101. Vec3 rotP = rot * p;
  102. sphereLines->push_back(rotPrev);
  103. sphereLines->push_back(rotP);
  104. Mat3 rot2(Euler(0.0, 0.0, Math::PI / 2));
  105. sphereLines->push_back(rot2 * rotPrev);
  106. sphereLines->push_back(rot2 * rotP);
  107. }
  108. prev = p;
  109. }
  110. }
  111. // Render
  112. //
  113. modelMat = modelMat * Mat4(Vec3(0.0), Mat3::getIdentity(), radius);
  114. begin();
  115. for(const Vec3& p : *sphereLines)
  116. {
  117. if(pointIndex >= MAX_POINTS_PER_DRAW)
  118. {
  119. end();
  120. begin();
  121. }
  122. pushBackVertex(p);
  123. }
  124. end();
  125. }
  126. //==============================================================================
  127. void DebugDrawer::drawCube(float size)
  128. {
  129. Vec3 maxPos = Vec3(0.5 * size);
  130. Vec3 minPos = Vec3(-0.5 * size);
  131. std::array<Vec3, 8> points = {{
  132. Vec3(maxPos.x(), maxPos.y(), maxPos.z()), // right top front
  133. Vec3(minPos.x(), maxPos.y(), maxPos.z()), // left top front
  134. Vec3(minPos.x(), minPos.y(), maxPos.z()), // left bottom front
  135. Vec3(maxPos.x(), minPos.y(), maxPos.z()), // right bottom front
  136. Vec3(maxPos.x(), maxPos.y(), minPos.z()), // right top back
  137. Vec3(minPos.x(), maxPos.y(), minPos.z()), // left top back
  138. Vec3(minPos.x(), minPos.y(), minPos.z()), // left bottom back
  139. Vec3(maxPos.x(), minPos.y(), minPos.z()) // right bottom back
  140. }};
  141. std::array<uint, 24> indeces = {{0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6,
  142. 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7}};
  143. begin();
  144. for(uint id : indeces)
  145. {
  146. pushBackVertex(points[id]);
  147. }
  148. end();
  149. }
  150. //==============================================================================
  151. void DebugDrawer::setModelMat(const Mat4& modelMat_)
  152. {
  153. ANKI_ASSERT(pointIndex == 0
  154. && "The func called after begin and before end");
  155. modelMat = modelMat_;
  156. }
  157. //==============================================================================
  158. void DebugDrawer::begin()
  159. {
  160. ANKI_ASSERT(pointIndex == 0);
  161. }
  162. //==============================================================================
  163. void DebugDrawer::end()
  164. {
  165. ANKI_ASSERT(pointIndex != 0);
  166. positionsVbo.write(&positions[0], 0, sizeof(Vec3) * pointIndex);
  167. colorsVbo.write(&colors[0], 0, sizeof(Vec3) * pointIndex);
  168. Mat4 pmv = vpMat * modelMat;
  169. sProg->findUniformVariableByName("modelViewProjectionMat").set(pmv);
  170. vao.bind();
  171. glDrawArrays(GL_LINES, 0, pointIndex);
  172. vao.unbind();
  173. // Cleanup
  174. pointIndex = 0;
  175. }
  176. //==============================================================================
  177. void DebugDrawer::pushBackVertex(const Vec3& pos)
  178. {
  179. positions[pointIndex] = pos;
  180. colors[pointIndex] = crntCol;
  181. ++pointIndex;
  182. }
  183. //==============================================================================
  184. // CollisionDebugDrawer =
  185. //==============================================================================
  186. //==============================================================================
  187. void CollisionDebugDrawer::visit(const Sphere& sphere)
  188. {
  189. dbg->setModelMat(Mat4(sphere.getCenter(), Mat3::getIdentity(), 1.0));
  190. dbg->drawSphere(sphere.getRadius());
  191. }
  192. //==============================================================================
  193. void CollisionDebugDrawer::visit(const Obb& obb)
  194. {
  195. Mat4 scale(Mat4::getIdentity());
  196. scale(0, 0) = obb.getExtend().x();
  197. scale(1, 1) = obb.getExtend().y();
  198. scale(2, 2) = obb.getExtend().z();
  199. Mat4 rot(obb.getRotation());
  200. Mat4 trs(obb.getCenter());
  201. Mat4 tsl;
  202. tsl = Mat4::combineTransformations(rot, scale);
  203. tsl = Mat4::combineTransformations(trs, tsl);
  204. dbg->setModelMat(tsl);
  205. dbg->setColor(Vec3(1.0, 1.0, 0.0));
  206. dbg->drawCube(2.0);
  207. }
  208. //==============================================================================
  209. void CollisionDebugDrawer::visit(const Plane& plane)
  210. {
  211. const Vec3& n = plane.getNormal();
  212. const float& o = plane.getOffset();
  213. Quat q;
  214. q.setFrom2Vec3(Vec3(0.0, 0.0, 1.0), n);
  215. Mat3 rot(q);
  216. rot.rotateXAxis(Math::PI / 2);
  217. Mat4 trf(n * o, rot);
  218. dbg->setModelMat(trf);
  219. dbg->drawGrid();
  220. }
  221. //==============================================================================
  222. void CollisionDebugDrawer::visit(const Aabb& aabb)
  223. {
  224. const Vec3& min = aabb.getMin();
  225. const Vec3& max = aabb.getMax();
  226. Mat4 trf = Mat4::getIdentity();
  227. // Scale
  228. for(uint i = 0; i < 3; ++i)
  229. {
  230. trf(i, i) = max[i] - min[i];
  231. }
  232. // Translation
  233. trf.setTranslationPart((max + min) / 2.0);
  234. dbg->setModelMat(trf);
  235. dbg->drawCube();
  236. }
  237. //==============================================================================
  238. void CollisionDebugDrawer::visit(const Frustum& f)
  239. {
  240. switch(f.getFrustumType())
  241. {
  242. case Frustum::FT_ORTHOGRAPHIC:
  243. visit(static_cast<const OrthographicFrustum&>(f).getObb());
  244. break;
  245. case Frustum::FT_PERSPECTIVE:
  246. {
  247. dbg->setColor(Vec4(1.0, 0.0, 1.0, 1.0));
  248. const PerspectiveFrustum& pf =
  249. static_cast<const PerspectiveFrustum&>(f);
  250. float camLen = pf.getFar();
  251. float tmp0 = camLen / tan((Math::PI - pf.getFovX()) * 0.5) + 0.001;
  252. float tmp1 = camLen * tan(pf.getFovY() * 0.5) + 0.001;
  253. Vec3 points[] = {
  254. Vec3(0.0, 0.0, 0.0), // 0: eye point
  255. Vec3(-tmp0, tmp1, -camLen), // 1: top left
  256. Vec3(-tmp0, -tmp1, -camLen), // 2: bottom left
  257. Vec3(tmp0, -tmp1, -camLen), // 3: bottom right
  258. Vec3(tmp0, tmp1, -camLen) // 4: top right
  259. };
  260. const uint indeces[] = {0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2,
  261. 3, 3, 4, 4, 1};
  262. dbg->begin();
  263. for(uint i = 0; i < sizeof(indeces) / sizeof(uint); i++)
  264. {
  265. dbg->pushBackVertex(points[indeces[i]]);
  266. }
  267. dbg->end();
  268. break;
  269. }
  270. }
  271. }
  272. //==============================================================================
  273. // PhysicsDebugDrawer =
  274. //==============================================================================
  275. //==============================================================================
  276. void PhysicsDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
  277. const btVector3& color)
  278. {
  279. dbg->drawLine(toAnki(from), toAnki(to), Vec4(toAnki(color), 1.0));
  280. }
  281. //==============================================================================
  282. void PhysicsDebugDrawer::drawSphere(btScalar radius,
  283. const btTransform& transform,
  284. const btVector3& color)
  285. {
  286. dbg->setColor(toAnki(color));
  287. dbg->setModelMat(Mat4(toAnki(transform)));
  288. dbg->drawSphere(radius);
  289. }
  290. //==============================================================================
  291. void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
  292. const btVector3& color)
  293. {
  294. Mat4 trf(Mat4::getIdentity());
  295. trf(0, 0) = max.getX() - min.getX();
  296. trf(1, 1) = max.getY() - min.getY();
  297. trf(2, 2) = max.getZ() - min.getZ();
  298. trf(0, 3) = (max.getX() + min.getX()) / 2.0;
  299. trf(1, 3) = (max.getY() + min.getY()) / 2.0;
  300. trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
  301. dbg->setModelMat(trf);
  302. dbg->setColor(toAnki(color));
  303. dbg->drawCube(1.0);
  304. }
  305. //==============================================================================
  306. void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
  307. const btTransform& trans, const btVector3& color)
  308. {
  309. Mat4 trf(Mat4::getIdentity());
  310. trf(0, 0) = max.getX() - min.getX();
  311. trf(1, 1) = max.getY() - min.getY();
  312. trf(2, 2) = max.getZ() - min.getZ();
  313. trf(0, 3) = (max.getX() + min.getX()) / 2.0;
  314. trf(1, 3) = (max.getY() + min.getY()) / 2.0;
  315. trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
  316. trf = Mat4::combineTransformations(Mat4(toAnki(trans)), trf);
  317. dbg->setModelMat(trf);
  318. dbg->setColor(toAnki(color));
  319. dbg->drawCube(1.0);
  320. }
  321. //==============================================================================
  322. void PhysicsDebugDrawer::drawContactPoint(const btVector3& /*pointOnB*/,
  323. const btVector3& /*normalOnB*/,
  324. btScalar /*distance*/, int /*lifeTime*/, const btVector3& /*color*/)
  325. {
  326. //ANKI_WARNING("Unimplemented");
  327. }
  328. //==============================================================================
  329. void PhysicsDebugDrawer::reportErrorWarning(const char* warningString)
  330. {
  331. throw ANKI_EXCEPTION(warningString);
  332. }
  333. //==============================================================================
  334. void PhysicsDebugDrawer::draw3dText(const btVector3& /*location*/,
  335. const char* /*textString*/)
  336. {
  337. //ANKI_WARNING("Unimplemented");
  338. }
  339. //==============================================================================
  340. // SceneDebugDrawer =
  341. //==============================================================================
  342. //==============================================================================
  343. void SceneDebugDrawer::draw(const SceneNode& node)
  344. {
  345. if(isFlagEnabled(DF_FRUSTUMABLE) && node.getFrustumable())
  346. {
  347. draw(*node.getFrustumable());
  348. }
  349. if(isFlagEnabled(DF_SPATIAL) && node.getSpatial())
  350. {
  351. draw(*node.getSpatial());
  352. }
  353. }
  354. //==============================================================================
  355. void SceneDebugDrawer::draw(const Frustumable& fr) const
  356. {
  357. const Frustum& fs = fr.getFrustum();
  358. CollisionDebugDrawer coldraw(dbg);
  359. fs.accept(coldraw);
  360. }
  361. //==============================================================================
  362. void SceneDebugDrawer::draw(const Spatial& x) const
  363. {
  364. const CollisionShape& cs = x.getSpatialCollisionShape();
  365. CollisionDebugDrawer coldraw(dbg);
  366. cs.accept(coldraw);
  367. }
  368. //==============================================================================
  369. void SceneDebugDrawer::draw(const Octree& octree) const
  370. {
  371. dbg->setColor(Vec3(1.0));
  372. draw(octree.getRoot(), 0, octree);
  373. }
  374. //==============================================================================
  375. void SceneDebugDrawer::draw(const OctreeNode& octnode, uint depth,
  376. const Octree& octree) const
  377. {
  378. Vec3 color = Vec3(1.0 - float(depth) / float(octree.getMaxDepth()));
  379. dbg->setColor(color);
  380. CollisionDebugDrawer v(dbg);
  381. octnode.getAabb().accept(v);
  382. // Children
  383. for(uint i = 0; i < 8; ++i)
  384. {
  385. if(octnode.getChildren()[i] != NULL)
  386. {
  387. draw(*octnode.getChildren()[i], depth + 1, octree);
  388. }
  389. }
  390. }
  391. //==============================================================================
  392. // SceneDrawer =
  393. //==============================================================================
  394. /// Set the uniform using this visitor
  395. struct SetUniformVisitor: public boost::static_visitor<void>
  396. {
  397. const ShaderProgramUniformVariable* uni;
  398. uint* texUnit;
  399. template<typename Type>
  400. void operator()(const Type& x) const
  401. {
  402. uni->set(x);
  403. }
  404. void operator()(const TextureResourcePointer& x) const
  405. {
  406. uni->set(*x, (*texUnit)++);
  407. }
  408. };
  409. //==============================================================================
  410. void SceneDrawer::setupShaderProg(
  411. const PassLevelKey& key,
  412. const Camera& cam,
  413. SceneNode& renderable)
  414. {
  415. const Material& mtl = renderable.getRenderable()->getMaterial();
  416. const ShaderProgram& sprog = mtl.getShaderProgram(key);
  417. uint texunit = 0;
  418. sprog.bind();
  419. SetUniformVisitor vis;
  420. vis.texUnit = &texunit;
  421. for(const MaterialVariable& mv : mtl.getVariables())
  422. {
  423. if(!mv.inPass(key))
  424. {
  425. continue;
  426. }
  427. const ShaderProgramUniformVariable& uni =
  428. mv.getShaderProgramUniformVariable(key);
  429. vis.uni = &uni;
  430. const std::string& name = uni.getName();
  431. if(name == "modelViewProjectionMat")
  432. {
  433. Mat4 mvp =
  434. Mat4(renderable.findPropertyBaseByName("worldTransform").
  435. getValue<Transform>())
  436. * cam.getViewMatrix() * cam.getProjectionMatrix();
  437. uni.set(mvp);
  438. }
  439. else
  440. {
  441. boost::apply_visitor(vis, mv.getVariant());
  442. }
  443. }
  444. }
  445. //==============================================================================
  446. void SceneDrawer::render(const Camera& cam, uint pass,
  447. SceneNode& node)
  448. {
  449. /*float dist = (node.getWorldTransform().getOrigin() -
  450. cam.getWorldTransform().getOrigin()).getLength();
  451. uint lod = std::min(r.calculateLod(dist), mtl.getLevelsOfDetail() - 1);*/
  452. PassLevelKey key(pass, 0);
  453. // Setup shader
  454. setupShaderProg(key, cam, node);
  455. // Render
  456. uint indecesNum =
  457. node.getRenderable()->getModelPatchBase().getIndecesNumber(0);
  458. node.getRenderable()->getModelPatchBase().getVao(key).bind();
  459. glDrawElements(GL_TRIANGLES, indecesNum, GL_UNSIGNED_SHORT, 0);
  460. node.getRenderable()->getModelPatchBase().getVao(key).unbind();
  461. }
  462. } // namespace anki