Renderer.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include "anki/renderer/Renderer.h"
  2. #include "anki/renderer/RendererInitializer.h"
  3. #include "anki/util/Exception.h"
  4. #include "anki/scene/Camera.h"
  5. namespace anki {
  6. //==============================================================================
  7. Renderer::Renderer()
  8. : ms(*this), is(*this), pps(*this), bs(*this), width(640), height(480),
  9. sceneDrawer(this)
  10. {
  11. enableStagesProfilingFlag = false;
  12. lodDistance = 10.0;
  13. }
  14. //==============================================================================
  15. Renderer::~Renderer()
  16. {}
  17. //==============================================================================
  18. void Renderer::init(const RendererInitializer& initializer)
  19. {
  20. // set from the initializer
  21. width = initializer.width;
  22. height = initializer.height;
  23. framesNum = 0;
  24. // a few sanity checks
  25. if(width < 10 || height < 10)
  26. {
  27. throw ANKI_EXCEPTION("Incorrect sizes");
  28. }
  29. // init the stages. Careful with the order!!!!!!!!!!
  30. ms.init(initializer);
  31. is.init(initializer);
  32. pps.init(initializer);
  33. bs.init(initializer);
  34. // quad VBOs and VAO
  35. float quadVertCoords[][2] = {{1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0},
  36. {1.0, 0.0}};
  37. quadPositionsVbo.create(GL_ARRAY_BUFFER, sizeof(quadVertCoords),
  38. quadVertCoords, GL_STATIC_DRAW);
  39. ushort quadVertIndeces[2][3] = {{0, 1, 3}, {1, 2, 3}}; // 2 triangles
  40. quadVertIndecesVbo.create(GL_ELEMENT_ARRAY_BUFFER, sizeof(quadVertIndeces),
  41. quadVertIndeces, GL_STATIC_DRAW);
  42. quadVao.create();
  43. quadVao.attachArrayBufferVbo(quadPositionsVbo, 0, 2, GL_FLOAT, false, 0,
  44. NULL);
  45. quadVao.attachElementArrayBufferVbo(quadVertIndecesVbo);
  46. // Other
  47. msTq.reset(new TimeQuery);
  48. isTq.reset(new TimeQuery);
  49. ppsTq.reset(new TimeQuery);
  50. bsTq.reset(new TimeQuery);
  51. }
  52. //==============================================================================
  53. void Renderer::render(Camera& cam_)
  54. {
  55. cam = &cam_;
  56. //
  57. // Calc a few vars
  58. //
  59. calcPlanes(Vec2(cam->getNear(), cam->getFar()), planes);
  60. ANKI_ASSERT(cam->getCameraType() == Camera::CT_PERSPECTIVE);
  61. const PerspectiveCamera& pcam = static_cast<const PerspectiveCamera&>(*cam);
  62. calcLimitsOfNearPlane(pcam, limitsOfNearPlane);
  63. limitsOfNearPlane2 = limitsOfNearPlane * 2.0;
  64. viewProjectionMat = cam->getProjectionMatrix() * cam->getViewMatrix();
  65. if(enableStagesProfilingFlag)
  66. {
  67. msTq->begin();
  68. ms.run();
  69. msTime = msTq->end();
  70. isTq->begin();
  71. is.run();
  72. isTime = isTq->end();
  73. ppsTq->begin();
  74. pps.runPrePass();
  75. ppsTime = ppsTq->end();
  76. bsTq->begin();
  77. bs.run();
  78. bsTime = bsTq->end();
  79. ppsTq->begin();
  80. pps.runPostPass();
  81. ppsTime += ppsTq->end();
  82. }
  83. else
  84. {
  85. ms.run();
  86. is.run();
  87. pps.runPrePass();
  88. bs.run();
  89. pps.runPostPass();
  90. }
  91. ++framesNum;
  92. }
  93. //==============================================================================
  94. void Renderer::drawQuad()
  95. {
  96. quadVao.bind();
  97. glDrawElements(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, 0);
  98. quadVao.unbind();
  99. ANKI_CHECK_GL_ERROR();
  100. }
  101. //==============================================================================
  102. Vec3 Renderer::unproject(const Vec3& windowCoords, const Mat4& modelViewMat,
  103. const Mat4& projectionMat, const int view[4])
  104. {
  105. Mat4 invPm = projectionMat * modelViewMat;
  106. invPm.invert();
  107. // the vec is in NDC space meaning: -1<=vec.x<=1 -1<=vec.y<=1 -1<=vec.z<=1
  108. Vec4 vec;
  109. vec.x() = (2.0 * (windowCoords.x() - view[0])) / view[2] - 1.0;
  110. vec.y() = (2.0 * (windowCoords.y() - view[1])) / view[3] - 1.0;
  111. vec.z() = 2.0 * windowCoords.z() - 1.0;
  112. vec.w() = 1.0;
  113. Vec4 final = invPm * vec;
  114. final /= final.w();
  115. return Vec3(final);
  116. }
  117. //==============================================================================
  118. void Renderer::createFai(uint width, uint height, int internalFormat,
  119. int format, int type, Texture& fai)
  120. {
  121. Texture::Initializer init;
  122. init.width = width;
  123. init.height = height;
  124. init.internalFormat = internalFormat;
  125. init.format = format;
  126. init.type = type;
  127. init.data = NULL;
  128. init.mipmapping = false;
  129. init.filteringType = Texture::TFT_LINEAR;
  130. init.repeat = false;
  131. init.anisotropyLevel = 0;
  132. fai.create(init);
  133. }
  134. //==============================================================================
  135. void Renderer::calcPlanes(const Vec2& cameraRange, Vec2& planes)
  136. {
  137. float zNear = cameraRange.x();
  138. float zFar = cameraRange.y();
  139. planes.x() = zFar / (zNear - zFar);
  140. planes.y() = (zFar * zNear) / (zNear -zFar);
  141. }
  142. //==============================================================================
  143. void Renderer::calcLimitsOfNearPlane(const PerspectiveCamera& pcam,
  144. Vec2& limitsOfNearPlane)
  145. {
  146. limitsOfNearPlane.y() = pcam.getNear() * tan(0.5 * pcam.getFovY());
  147. limitsOfNearPlane.x() = limitsOfNearPlane.y()
  148. * (pcam.getFovX() / pcam.getFovY());
  149. }
  150. } // end namespace