Drawer.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. #include "anki/renderer/Drawer.h"
  2. #include "anki/resource/ShaderProgramResource.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. #include "anki/resource/TextureResource.h"
  12. #include "anki/renderer/Renderer.h"
  13. namespace anki {
  14. //==============================================================================
  15. // DebugDrawer =
  16. //==============================================================================
  17. //==============================================================================
  18. DebugDrawer::~DebugDrawer()
  19. {}
  20. //==============================================================================
  21. DebugDrawer::DebugDrawer()
  22. {
  23. sProg.load("shaders/Dbg.glsl");
  24. positionsVbo.create(GL_ARRAY_BUFFER, sizeof(positions), NULL,
  25. GL_DYNAMIC_DRAW);
  26. colorsVbo.create(GL_ARRAY_BUFFER, sizeof(colors), NULL, GL_DYNAMIC_DRAW);
  27. vao.create();
  28. const int positionAttribLoc = 0;
  29. vao.attachArrayBufferVbo(positionsVbo, positionAttribLoc, 3, GL_FLOAT,
  30. GL_FALSE, 0, NULL);
  31. const int colorAttribLoc = 1;
  32. vao.attachArrayBufferVbo(colorsVbo, colorAttribLoc, 3, GL_FLOAT, GL_FALSE,
  33. 0, NULL);
  34. pointIndex = 0;
  35. modelMat.setIdentity();
  36. crntCol = Vec3(1.0, 0.0, 0.0);
  37. }
  38. //==============================================================================
  39. void DebugDrawer::drawLine(const Vec3& from, const Vec3& to, const Vec4& color)
  40. {
  41. setColor(color);
  42. begin();
  43. pushBackVertex(from);
  44. pushBackVertex(to);
  45. end();
  46. }
  47. //==============================================================================
  48. void DebugDrawer::drawGrid()
  49. {
  50. Vec4 col0(0.5, 0.5, 0.5, 1.0);
  51. Vec4 col1(0.0, 0.0, 1.0, 1.0);
  52. Vec4 col2(1.0, 0.0, 0.0, 1.0);
  53. const float SPACE = 1.0; // space between lines
  54. const int NUM = 57; // lines number. must be odd
  55. const float GRID_HALF_SIZE = ((NUM - 1) * SPACE / 2);
  56. setColor(col0);
  57. begin();
  58. for(int x = - NUM / 2 * SPACE; x < NUM / 2 * SPACE; x += SPACE)
  59. {
  60. setColor(col0);
  61. // if the middle line then change color
  62. if(x == 0)
  63. {
  64. setColor(col1);
  65. }
  66. // line in z
  67. pushBackVertex(Vec3(x, 0.0, -GRID_HALF_SIZE));
  68. pushBackVertex(Vec3(x, 0.0, GRID_HALF_SIZE));
  69. // if middle line change col so you can highlight the x-axis
  70. if(x == 0)
  71. {
  72. setColor(col2);
  73. }
  74. // line in the x
  75. pushBackVertex(Vec3(-GRID_HALF_SIZE, 0.0, x));
  76. pushBackVertex(Vec3(GRID_HALF_SIZE, 0.0, x));
  77. }
  78. // render
  79. end();
  80. }
  81. //==============================================================================
  82. void DebugDrawer::drawSphere(float radius, int complexity)
  83. {
  84. std::vector<Vec3>* sphereLines;
  85. // Pre-calculate the sphere points5
  86. //
  87. std::map<uint, std::vector<Vec3> >::iterator it =
  88. complexityToPreCalculatedSphere.find(complexity);
  89. if(it != complexityToPreCalculatedSphere.end()) // Found
  90. {
  91. sphereLines = &(it->second);
  92. }
  93. else // Not found
  94. {
  95. complexityToPreCalculatedSphere[complexity] = std::vector<Vec3>();
  96. sphereLines = &complexityToPreCalculatedSphere[complexity];
  97. float fi = Math::PI / complexity;
  98. Vec3 prev(1.0, 0.0, 0.0);
  99. for(float th = fi; th < Math::PI * 2.0 + fi; th += fi)
  100. {
  101. Vec3 p = Mat3(Euler(0.0, th, 0.0)) * Vec3(1.0, 0.0, 0.0);
  102. for(float th2 = 0.0; th2 < Math::PI; th2 += fi)
  103. {
  104. Mat3 rot(Euler(th2, 0.0, 0.0));
  105. Vec3 rotPrev = rot * prev;
  106. Vec3 rotP = rot * p;
  107. sphereLines->push_back(rotPrev);
  108. sphereLines->push_back(rotP);
  109. Mat3 rot2(Euler(0.0, 0.0, Math::PI / 2));
  110. sphereLines->push_back(rot2 * rotPrev);
  111. sphereLines->push_back(rot2 * rotP);
  112. }
  113. prev = p;
  114. }
  115. }
  116. // Render
  117. //
  118. modelMat = modelMat * Mat4(Vec3(0.0), Mat3::getIdentity(), radius);
  119. begin();
  120. for(const Vec3& p : *sphereLines)
  121. {
  122. if(pointIndex >= MAX_POINTS_PER_DRAW)
  123. {
  124. end();
  125. begin();
  126. }
  127. pushBackVertex(p);
  128. }
  129. end();
  130. }
  131. //==============================================================================
  132. void DebugDrawer::drawCube(float size)
  133. {
  134. Vec3 maxPos = Vec3(0.5 * size);
  135. Vec3 minPos = Vec3(-0.5 * size);
  136. std::array<Vec3, 8> points = {{
  137. Vec3(maxPos.x(), maxPos.y(), maxPos.z()), // right top front
  138. Vec3(minPos.x(), maxPos.y(), maxPos.z()), // left top front
  139. Vec3(minPos.x(), minPos.y(), maxPos.z()), // left bottom front
  140. Vec3(maxPos.x(), minPos.y(), maxPos.z()), // right bottom front
  141. Vec3(maxPos.x(), maxPos.y(), minPos.z()), // right top back
  142. Vec3(minPos.x(), maxPos.y(), minPos.z()), // left top back
  143. Vec3(minPos.x(), minPos.y(), minPos.z()), // left bottom back
  144. Vec3(maxPos.x(), minPos.y(), minPos.z()) // right bottom back
  145. }};
  146. std::array<uint, 24> indeces = {{0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6,
  147. 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7}};
  148. begin();
  149. for(uint id : indeces)
  150. {
  151. pushBackVertex(points[id]);
  152. }
  153. end();
  154. }
  155. //==============================================================================
  156. void DebugDrawer::setModelMatrix(const Mat4& modelMat_)
  157. {
  158. ANKI_ASSERT(pointIndex == 0
  159. && "The func called after begin and before end");
  160. modelMat = modelMat_;
  161. }
  162. //==============================================================================
  163. void DebugDrawer::begin()
  164. {
  165. ANKI_ASSERT(pointIndex == 0);
  166. }
  167. //==============================================================================
  168. void DebugDrawer::end()
  169. {
  170. ANKI_ASSERT(pointIndex != 0);
  171. positionsVbo.write(&positions[0], 0, sizeof(Vec3) * pointIndex);
  172. colorsVbo.write(&colors[0], 0, sizeof(Vec3) * pointIndex);
  173. Mat4 pmv = vpMat * modelMat;
  174. sProg->bind();
  175. sProg->findUniformVariable("modelViewProjectionMat").set(pmv);
  176. vao.bind();
  177. glDrawArrays(GL_LINES, 0, pointIndex);
  178. vao.unbind();
  179. // Cleanup
  180. pointIndex = 0;
  181. }
  182. //==============================================================================
  183. void DebugDrawer::pushBackVertex(const Vec3& pos)
  184. {
  185. positions[pointIndex] = pos;
  186. colors[pointIndex] = crntCol;
  187. ++pointIndex;
  188. }
  189. //==============================================================================
  190. // CollisionDebugDrawer =
  191. //==============================================================================
  192. //==============================================================================
  193. void CollisionDebugDrawer::visit(const Sphere& sphere)
  194. {
  195. dbg->setModelMatrix(Mat4(sphere.getCenter(), Mat3::getIdentity(), 1.0));
  196. dbg->drawSphere(sphere.getRadius());
  197. }
  198. //==============================================================================
  199. void CollisionDebugDrawer::visit(const Obb& obb)
  200. {
  201. Mat4 scale(Mat4::getIdentity());
  202. scale(0, 0) = obb.getExtend().x();
  203. scale(1, 1) = obb.getExtend().y();
  204. scale(2, 2) = obb.getExtend().z();
  205. Mat4 rot(obb.getRotation());
  206. Mat4 trs(obb.getCenter());
  207. Mat4 tsl;
  208. tsl = Mat4::combineTransformations(rot, scale);
  209. tsl = Mat4::combineTransformations(trs, tsl);
  210. dbg->setModelMatrix(tsl);
  211. dbg->setColor(Vec3(1.0, 1.0, 0.0));
  212. dbg->drawCube(2.0);
  213. }
  214. //==============================================================================
  215. void CollisionDebugDrawer::visit(const Plane& plane)
  216. {
  217. const Vec3& n = plane.getNormal();
  218. const float& o = plane.getOffset();
  219. Quat q;
  220. q.setFrom2Vec3(Vec3(0.0, 0.0, 1.0), n);
  221. Mat3 rot(q);
  222. rot.rotateXAxis(Math::PI / 2.0);
  223. Mat4 trf(n * o, rot);
  224. dbg->setModelMatrix(trf);
  225. dbg->drawGrid();
  226. }
  227. //==============================================================================
  228. void CollisionDebugDrawer::visit(const Aabb& aabb)
  229. {
  230. const Vec3& min = aabb.getMin();
  231. const Vec3& max = aabb.getMax();
  232. Mat4 trf = Mat4::getIdentity();
  233. // Scale
  234. for(uint i = 0; i < 3; ++i)
  235. {
  236. trf(i, i) = max[i] - min[i];
  237. }
  238. // Translation
  239. trf.setTranslationPart((max + min) / 2.0);
  240. dbg->setModelMatrix(trf);
  241. dbg->drawCube();
  242. }
  243. //==============================================================================
  244. void CollisionDebugDrawer::visit(const Frustum& f)
  245. {
  246. switch(f.getFrustumType())
  247. {
  248. case Frustum::FT_ORTHOGRAPHIC:
  249. visit(static_cast<const OrthographicFrustum&>(f).getObb());
  250. break;
  251. case Frustum::FT_PERSPECTIVE:
  252. {
  253. dbg->setColor(Vec4(0.5, 0.0, 0.5, 1.0));
  254. const PerspectiveFrustum& pf =
  255. static_cast<const PerspectiveFrustum&>(f);
  256. float camLen = pf.getFar();
  257. float tmp0 = camLen / tan((Math::PI - pf.getFovX()) * 0.5) + 0.001;
  258. float tmp1 = camLen * tan(pf.getFovY() * 0.5) + 0.001;
  259. Vec3 points[] = {
  260. Vec3(0.0, 0.0, 0.0), // 0: eye point
  261. Vec3(-tmp0, tmp1, -camLen), // 1: top left
  262. Vec3(-tmp0, -tmp1, -camLen), // 2: bottom left
  263. Vec3(tmp0, -tmp1, -camLen), // 3: bottom right
  264. Vec3(tmp0, tmp1, -camLen) // 4: top right
  265. };
  266. const uint indeces[] = {0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2,
  267. 3, 3, 4, 4, 1};
  268. dbg->begin();
  269. for(uint i = 0; i < sizeof(indeces) / sizeof(uint); i++)
  270. {
  271. dbg->pushBackVertex(points[indeces[i]]);
  272. }
  273. dbg->end();
  274. break;
  275. }
  276. }
  277. }
  278. //==============================================================================
  279. // PhysicsDebugDrawer =
  280. //==============================================================================
  281. //==============================================================================
  282. void PhysicsDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
  283. const btVector3& color)
  284. {
  285. dbg->drawLine(toAnki(from), toAnki(to), Vec4(toAnki(color), 1.0));
  286. }
  287. //==============================================================================
  288. void PhysicsDebugDrawer::drawSphere(btScalar radius,
  289. const btTransform& transform,
  290. const btVector3& color)
  291. {
  292. dbg->setColor(toAnki(color));
  293. dbg->setModelMatrix(Mat4(toAnki(transform)));
  294. dbg->drawSphere(radius);
  295. }
  296. //==============================================================================
  297. void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
  298. const btVector3& color)
  299. {
  300. Mat4 trf(Mat4::getIdentity());
  301. trf(0, 0) = max.getX() - min.getX();
  302. trf(1, 1) = max.getY() - min.getY();
  303. trf(2, 2) = max.getZ() - min.getZ();
  304. trf(0, 3) = (max.getX() + min.getX()) / 2.0;
  305. trf(1, 3) = (max.getY() + min.getY()) / 2.0;
  306. trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
  307. dbg->setModelMatrix(trf);
  308. dbg->setColor(toAnki(color));
  309. dbg->drawCube(1.0);
  310. }
  311. //==============================================================================
  312. void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
  313. const btTransform& trans, const btVector3& color)
  314. {
  315. Mat4 trf(Mat4::getIdentity());
  316. trf(0, 0) = max.getX() - min.getX();
  317. trf(1, 1) = max.getY() - min.getY();
  318. trf(2, 2) = max.getZ() - min.getZ();
  319. trf(0, 3) = (max.getX() + min.getX()) / 2.0;
  320. trf(1, 3) = (max.getY() + min.getY()) / 2.0;
  321. trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
  322. trf = Mat4::combineTransformations(Mat4(toAnki(trans)), trf);
  323. dbg->setModelMatrix(trf);
  324. dbg->setColor(toAnki(color));
  325. dbg->drawCube(1.0);
  326. }
  327. //==============================================================================
  328. void PhysicsDebugDrawer::drawContactPoint(const btVector3& /*pointOnB*/,
  329. const btVector3& /*normalOnB*/,
  330. btScalar /*distance*/, int /*lifeTime*/, const btVector3& /*color*/)
  331. {
  332. //ANKI_LOGW("Unimplemented");
  333. }
  334. //==============================================================================
  335. void PhysicsDebugDrawer::reportErrorWarning(const char* warningString)
  336. {
  337. throw ANKI_EXCEPTION(warningString);
  338. }
  339. //==============================================================================
  340. void PhysicsDebugDrawer::draw3dText(const btVector3& /*location*/,
  341. const char* /*textString*/)
  342. {
  343. //ANKI_LOGW("Unimplemented");
  344. }
  345. //==============================================================================
  346. // SceneDebugDrawer =
  347. //==============================================================================
  348. //==============================================================================
  349. void SceneDebugDrawer::draw(SceneNode& node)
  350. {
  351. // Nothing to render?
  352. if(getFlagsBitmask() == 0)
  353. {
  354. return;
  355. }
  356. Movable* mv = node.getMovable();
  357. if(mv)
  358. {
  359. dbg->setModelMatrix(Mat4(mv->getWorldTransform()));
  360. }
  361. else
  362. {
  363. dbg->setModelMatrix(Mat4::getIdentity());
  364. }
  365. Frustumable* fr;
  366. if(isFlagEnabled(DF_FRUSTUMABLE) && (fr = node.getFrustumable()))
  367. {
  368. draw(*fr);
  369. }
  370. Spatial* sp;
  371. if(isFlagEnabled(DF_SPATIAL) && (sp = node.getSpatial()))
  372. {
  373. draw(*sp);
  374. }
  375. }
  376. //==============================================================================
  377. void SceneDebugDrawer::draw(Frustumable& fr) const
  378. {
  379. const Frustum& fs = fr.getFrustum();
  380. CollisionDebugDrawer coldraw(dbg);
  381. fs.accept(coldraw);
  382. }
  383. //==============================================================================
  384. void SceneDebugDrawer::draw(Spatial& x) const
  385. {
  386. const CollisionShape& cs = x.getSpatialCollisionShape();
  387. CollisionDebugDrawer coldraw(dbg);
  388. cs.accept(coldraw);
  389. }
  390. //==============================================================================
  391. void SceneDebugDrawer::draw(const Octree& octree) const
  392. {
  393. dbg->setColor(Vec3(1.0));
  394. draw(octree.getRoot(), 0, octree);
  395. }
  396. //==============================================================================
  397. void SceneDebugDrawer::draw(const OctreeNode& octnode, uint32_t depth,
  398. const Octree& octree) const
  399. {
  400. Vec3 color = Vec3(1.0 - float(depth) / float(octree.getMaxDepth()));
  401. dbg->setColor(color);
  402. CollisionDebugDrawer v(dbg);
  403. octnode.getAabb().accept(v);
  404. // Children
  405. for(uint32_t i = 0; i < 8; ++i)
  406. {
  407. if(octnode.getChildren()[i] != NULL)
  408. {
  409. draw(*octnode.getChildren()[i], depth + 1, octree);
  410. }
  411. }
  412. }
  413. //==============================================================================
  414. // RenderableDrawer =
  415. //==============================================================================
  416. //==============================================================================
  417. enum BuildinId
  418. {
  419. BI_UNITIALIZED = 0,
  420. BT_NO_BUILDIN,
  421. BI_MODEL_VIEW_PROJECTION_MATRIX,
  422. BI_MODEL_VIEW_MATRIX,
  423. BI_NORMAL_MATRIX,
  424. BI_BLURRING,
  425. BI_COUNT
  426. };
  427. static std::array<const char*, BI_COUNT - 2> buildinNames = {{
  428. "modelViewProjectionMat",
  429. "modelViewMat",
  430. "normalMat",
  431. "blurring"
  432. }};
  433. template<typename T>
  434. static void uniSet(const ShaderProgramUniformVariable& uni, const T& x)
  435. {
  436. ANKI_ASSERT(0);
  437. }
  438. #define TEMPLATE_SPECIALIZATION(type) \
  439. template<> \
  440. void uniSet<type>(const ShaderProgramUniformVariable& uni, const type& x) \
  441. { \
  442. uni.set(x); \
  443. }
  444. TEMPLATE_SPECIALIZATION(float)
  445. TEMPLATE_SPECIALIZATION(Vec2)
  446. TEMPLATE_SPECIALIZATION(Vec3)
  447. TEMPLATE_SPECIALIZATION(Vec4)
  448. TEMPLATE_SPECIALIZATION(Mat3)
  449. TEMPLATE_SPECIALIZATION(Mat4)
  450. // Texture specialization
  451. template<>
  452. void uniSet<TextureResourcePointer>(
  453. const ShaderProgramUniformVariable& uni,
  454. const TextureResourcePointer& x)
  455. {
  456. const Texture* tex = x.get();
  457. uni.set(*tex);
  458. }
  459. /// XXX
  460. struct SetupMaterialVariableVisitor
  461. {
  462. PassLevelKey key;
  463. const Camera* cam = nullptr;
  464. Renderer* r = nullptr;
  465. Renderable* renderable = nullptr;
  466. template<typename TProp>
  467. void visit(TProp& x)
  468. {
  469. MaterialVariableProperty<typename TProp::Value>& mprop =
  470. static_cast<MaterialVariableProperty<typename TProp::Value>&>(x);
  471. const MaterialVariable& mv = mprop.getMaterialVariable();
  472. const ShaderProgramUniformVariable* uni =
  473. mv.findShaderProgramUniformVariable(key);
  474. if(!uni)
  475. {
  476. return;
  477. }
  478. // Set buildin id
  479. //
  480. if(mprop.getBuildinId() == BI_UNITIALIZED)
  481. {
  482. const std::string name = mv.getName();
  483. for(uint32_t i = 0; i < buildinNames.size(); i++)
  484. {
  485. if(name == buildinNames[i])
  486. {
  487. mprop.setBuildinId(i + 2);
  488. break;
  489. }
  490. }
  491. if(mprop.getBuildinId() == BI_UNITIALIZED)
  492. {
  493. mprop.setBuildinId(BT_NO_BUILDIN);
  494. }
  495. }
  496. // Sanity check
  497. //
  498. /*if(!mv.getInitialized() && mprop.getBuildinId() == BT_NO_BUILDIN)
  499. {
  500. ANKI_LOGW("Material variable no building and not initialized: "
  501. << mv.getName());
  502. }*/
  503. // Set uniform
  504. //
  505. const Transform* rwtrf = renderable->getRenderableWorldTransform();
  506. Mat4 mMat = (rwtrf) ? Mat4(*rwtrf) : Mat4::getIdentity();
  507. const Mat4& vpMat = cam->getViewProjectionMatrix();
  508. Mat4 mvpMat = vpMat * mMat;
  509. Mat4 mvMat;
  510. bool mvMatCalculated = false; // Opt
  511. switch(mprop.getBuildinId())
  512. {
  513. case BT_NO_BUILDIN:
  514. uniSet(*uni, mprop.getValue());
  515. break;
  516. case BI_MODEL_VIEW_PROJECTION_MATRIX:
  517. uni->set(mvpMat);
  518. break;
  519. case BI_MODEL_VIEW_MATRIX:
  520. if(!mvMatCalculated)
  521. {
  522. mvMat = mMat * cam->getViewMatrix();
  523. mvMatCalculated = true;
  524. }
  525. uni->set(mvMat);
  526. break;
  527. case BI_NORMAL_MATRIX:
  528. if(!mvMatCalculated)
  529. {
  530. mvMat = mMat * cam->getViewMatrix();
  531. mvMatCalculated = true;
  532. }
  533. uni->set(mvMat.getRotationPart());
  534. break;
  535. case BI_BLURRING:
  536. uni->set(0.0);
  537. break;
  538. }
  539. }
  540. };
  541. //==============================================================================
  542. void RenderableDrawer::setupShaderProg(
  543. const PassLevelKey& key,
  544. const Camera& cam,
  545. Renderable& renderable)
  546. {
  547. const Material& mtl = renderable.getMaterial();
  548. const ShaderProgram& sprog = mtl.findShaderProgram(key);
  549. if(mtl.getDepthTestingEnabled())
  550. {
  551. GlStateSingleton::get().enable(GL_DEPTH_TEST);
  552. }
  553. else
  554. {
  555. GlStateSingleton::get().disable(GL_DEPTH_TEST);
  556. }
  557. sprog.bind();
  558. SetupMaterialVariableVisitor vis;
  559. vis.cam = &cam;
  560. vis.key = key;
  561. vis.renderable = &renderable;
  562. vis.r = r;
  563. for(auto it = renderable.getPropertiesBegin();
  564. it != renderable.getPropertiesEnd(); ++it)
  565. {
  566. PropertyBase* pbase = *it;
  567. pbase->acceptVisitor(vis);
  568. }
  569. }
  570. //==============================================================================
  571. void RenderableDrawer::render(const Camera& cam, uint pass,
  572. Renderable& renderable)
  573. {
  574. /*float dist = (node.getWorldTransform().getOrigin() -
  575. cam.getWorldTransform().getOrigin()).getLength();
  576. uint lod = std::min(r.calculateLod(dist), mtl.getLevelsOfDetail() - 1);*/
  577. PassLevelKey key(pass, 0);
  578. // Setup shader
  579. setupShaderProg(key, cam, renderable);
  580. // Render
  581. uint32_t indecesNum =
  582. renderable.getModelPatchBase().getIndecesNumber(0);
  583. const Vao& vao = renderable.getModelPatchBase().getVao(key);
  584. ANKI_ASSERT(vao.getAttachmentsCount() > 1);
  585. vao.bind();
  586. glDrawElements(GL_TRIANGLES, indecesNum, GL_UNSIGNED_SHORT, 0);
  587. vao.unbind();
  588. }
  589. } // end namespace anki