Renderer.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include "anki/renderer/Renderer.h"
  2. #include "anki/util/Exception.h"
  3. #include "anki/scene/Camera.h"
  4. #include "anki/scene/SceneGraph.h"
  5. #include "anki/core/Counters.h"
  6. namespace anki {
  7. //==============================================================================
  8. Renderer::Renderer()
  9. : ms(this), is(this), pps(this), bs(this), sceneDrawer(this)
  10. {}
  11. //==============================================================================
  12. Renderer::~Renderer()
  13. {}
  14. //==============================================================================
  15. void Renderer::init(const RendererInitializer& initializer)
  16. {
  17. // set from the initializer
  18. width = initializer.width;
  19. height = initializer.height;
  20. lodDistance = initializer.lodDistance;
  21. framesNum = 0;
  22. // a few sanity checks
  23. if(width < 10 || height < 10)
  24. {
  25. throw ANKI_EXCEPTION("Incorrect sizes");
  26. }
  27. // init the stages. Careful with the order!!!!!!!!!!
  28. tiler.init(this);
  29. ms.init(initializer);;
  30. is.init(initializer);
  31. bs.init(initializer);
  32. pps.init(initializer);
  33. bs.init(initializer);
  34. // quad VBOs and VAO
  35. static const F32 quadVertCoords[][2] = {{1.0, 1.0}, {-1.0, 1.0},
  36. {-1.0, -1.0}, {1.0, -1.0}};
  37. quadPositionsVbo.create(GL_ARRAY_BUFFER, sizeof(quadVertCoords),
  38. quadVertCoords, GL_STATIC_DRAW);
  39. static const U16 quadVertIndeces[2][3] =
  40. {{0, 1, 3}, {1, 2, 3}}; // 2 triangles
  41. quadVertIndecesVbo.create(GL_ELEMENT_ARRAY_BUFFER, sizeof(quadVertIndeces),
  42. quadVertIndeces, GL_STATIC_DRAW);
  43. quadVao.create();
  44. quadVao.attachArrayBufferVbo(
  45. &quadPositionsVbo, 0, 2, GL_FLOAT, false, 0, 0);
  46. quadVao.attachElementArrayBufferVbo(&quadVertIndecesVbo);
  47. }
  48. //==============================================================================
  49. void Renderer::render(SceneGraph& scene_)
  50. {
  51. scene = &scene_;
  52. Camera& cam = scene->getActiveCamera();
  53. // Calc a few vars
  54. //
  55. U32 camUpdateTimestamp = cam.getFrustumable()->getFrustumableTimestamp();
  56. if(planesUpdateTimestamp < scene->getActiveCameraChangeTimestamp()
  57. || planesUpdateTimestamp < camUpdateTimestamp
  58. || planesUpdateTimestamp == 1)
  59. {
  60. calcPlanes(Vec2(cam.getNear(), cam.getFar()), planes);
  61. ANKI_ASSERT(cam.getCameraType() == Camera::CT_PERSPECTIVE);
  62. const PerspectiveCamera& pcam =
  63. static_cast<const PerspectiveCamera&>(cam);
  64. calcLimitsOfNearPlane(pcam, limitsOfNearPlane);
  65. limitsOfNearPlane2 = limitsOfNearPlane * 2.0;
  66. planesUpdateTimestamp = getGlobTimestamp();
  67. }
  68. viewProjectionMat = cam.getViewProjectionMatrix();
  69. ANKI_COUNTER_START_TIMER(C_RENDERER_MS_TIME);
  70. ms.run();
  71. ANKI_COUNTER_STOP_TIMER_INC(C_RENDERER_MS_TIME);
  72. tiler.runMinMax(ms.getDepthFai());
  73. ANKI_COUNTER_START_TIMER(C_RENDERER_IS_TIME);
  74. is.run();
  75. ANKI_COUNTER_STOP_TIMER_INC(C_RENDERER_IS_TIME);
  76. bs.run();
  77. ANKI_COUNTER_START_TIMER(C_RENDERER_PPS_TIME);
  78. pps.run();
  79. ANKI_COUNTER_STOP_TIMER_INC(C_RENDERER_PPS_TIME);
  80. ANKI_CHECK_GL_ERROR();
  81. ++framesNum;
  82. }
  83. //==============================================================================
  84. void Renderer::drawQuad()
  85. {
  86. quadVao.bind();
  87. glDrawElements(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, 0);
  88. }
  89. //==============================================================================
  90. void Renderer::drawQuadInstanced(U32 primitiveCount)
  91. {
  92. quadVao.bind();
  93. glDrawElementsInstanced(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, 0,
  94. primitiveCount);
  95. }
  96. //==============================================================================
  97. void Renderer::drawQuadMultiple(U times)
  98. {
  99. quadVao.bind();
  100. #if ANKI_GL == ANKI_GL_DESKTOP
  101. const U max_times = 16;
  102. Array<GLsizei, max_times> count;
  103. Array<const GLvoid*, max_times> indices;
  104. for(U i = 0; i < times; i++)
  105. {
  106. count[i] = 2 * 3;
  107. indices[i] = nullptr;
  108. }
  109. glMultiDrawElements(
  110. GL_TRIANGLES, &count[0], GL_UNSIGNED_SHORT, &indices[0], times);
  111. #else
  112. for(U i = 0; i < times; i++)
  113. {
  114. glDrawElements(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, 0);
  115. }
  116. #endif
  117. }
  118. //==============================================================================
  119. Vec3 Renderer::unproject(const Vec3& windowCoords, const Mat4& modelViewMat,
  120. const Mat4& projectionMat, const int view[4])
  121. {
  122. Mat4 invPm = projectionMat * modelViewMat;
  123. invPm.invert();
  124. // the vec is in NDC space meaning: -1<=vec.x<=1 -1<=vec.y<=1 -1<=vec.z<=1
  125. Vec4 vec;
  126. vec.x() = (2.0 * (windowCoords.x() - view[0])) / view[2] - 1.0;
  127. vec.y() = (2.0 * (windowCoords.y() - view[1])) / view[3] - 1.0;
  128. vec.z() = 2.0 * windowCoords.z() - 1.0;
  129. vec.w() = 1.0;
  130. Vec4 final = invPm * vec;
  131. final /= final.w();
  132. return Vec3(final);
  133. }
  134. //==============================================================================
  135. void Renderer::calcPlanes(const Vec2& cameraRange, Vec2& planes)
  136. {
  137. F32 zNear = cameraRange.x();
  138. F32 zFar = cameraRange.y();
  139. F32 opt = zNear - zFar;
  140. planes.x() = zFar / opt;
  141. planes.y() = (zFar * zNear) / opt;
  142. }
  143. //==============================================================================
  144. void Renderer::calcLimitsOfNearPlane(const PerspectiveCamera& pcam,
  145. Vec2& limitsOfNearPlane)
  146. {
  147. limitsOfNearPlane.y() = tan(0.5 * pcam.getFovY());
  148. limitsOfNearPlane.x() = tan(0.5 * pcam.getFovX());
  149. }
  150. //==============================================================================
  151. void Renderer::clearAfterBindingFbo(const GLenum cap)
  152. {
  153. if(GlStateCommonSingleton::get().getGpu() == GlStateCommon::GPU_ARM)
  154. {
  155. glClear(cap);
  156. }
  157. }
  158. } // end namespace anki