| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- #include "anki/renderer/Renderer.h"
- #include "anki/util/Exception.h"
- #include "anki/scene/Camera.h"
- #include "anki/scene/SceneGraph.h"
- #include "anki/core/Counters.h"
- namespace anki {
- //==============================================================================
- Renderer::Renderer()
- : ms(this), is(this), pps(this), bs(this), sceneDrawer(this)
- {}
- //==============================================================================
- Renderer::~Renderer()
- {}
- //==============================================================================
- void Renderer::init(const RendererInitializer& initializer)
- {
- // set from the initializer
- width = initializer.width;
- height = initializer.height;
- lodDistance = initializer.lodDistance;
- framesNum = 0;
- // a few sanity checks
- if(width < 10 || height < 10)
- {
- throw ANKI_EXCEPTION("Incorrect sizes");
- }
- // init the stages. Careful with the order!!!!!!!!!!
- tiler.init(this);
- ms.init(initializer);;
- is.init(initializer);
- bs.init(initializer);
- pps.init(initializer);
- bs.init(initializer);
- // quad VBOs and VAO
- static const F32 quadVertCoords[][2] = {{1.0, 1.0}, {-1.0, 1.0},
- {-1.0, -1.0}, {1.0, -1.0}};
- quadPositionsVbo.create(GL_ARRAY_BUFFER, sizeof(quadVertCoords),
- quadVertCoords, GL_STATIC_DRAW);
- static const U16 quadVertIndeces[2][3] =
- {{0, 1, 3}, {1, 2, 3}}; // 2 triangles
- quadVertIndecesVbo.create(GL_ELEMENT_ARRAY_BUFFER, sizeof(quadVertIndeces),
- quadVertIndeces, GL_STATIC_DRAW);
- quadVao.create();
- quadVao.attachArrayBufferVbo(
- &quadPositionsVbo, 0, 2, GL_FLOAT, false, 0, 0);
- quadVao.attachElementArrayBufferVbo(&quadVertIndecesVbo);
- }
- //==============================================================================
- void Renderer::render(SceneGraph& scene_)
- {
- scene = &scene_;
- Camera& cam = scene->getActiveCamera();
- // Calc a few vars
- //
- U32 camUpdateTimestamp = cam.getFrustumable()->getFrustumableTimestamp();
- if(planesUpdateTimestamp < scene->getActiveCameraChangeTimestamp()
- || planesUpdateTimestamp < camUpdateTimestamp
- || planesUpdateTimestamp == 1)
- {
- calcPlanes(Vec2(cam.getNear(), cam.getFar()), planes);
- ANKI_ASSERT(cam.getCameraType() == Camera::CT_PERSPECTIVE);
- const PerspectiveCamera& pcam =
- static_cast<const PerspectiveCamera&>(cam);
- calcLimitsOfNearPlane(pcam, limitsOfNearPlane);
- limitsOfNearPlane2 = limitsOfNearPlane * 2.0;
- planesUpdateTimestamp = getGlobTimestamp();
- }
- viewProjectionMat = cam.getViewProjectionMatrix();
- ANKI_COUNTER_START_TIMER(C_RENDERER_MS_TIME);
- ms.run();
- ANKI_COUNTER_STOP_TIMER_INC(C_RENDERER_MS_TIME);
- tiler.runMinMax(ms.getDepthFai());
- ANKI_COUNTER_START_TIMER(C_RENDERER_IS_TIME);
- is.run();
- ANKI_COUNTER_STOP_TIMER_INC(C_RENDERER_IS_TIME);
- bs.run();
- ANKI_COUNTER_START_TIMER(C_RENDERER_PPS_TIME);
- pps.run();
- ANKI_COUNTER_STOP_TIMER_INC(C_RENDERER_PPS_TIME);
- ANKI_CHECK_GL_ERROR();
- ++framesNum;
- }
- //==============================================================================
- void Renderer::drawQuad()
- {
- quadVao.bind();
- glDrawElements(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, 0);
- }
- //==============================================================================
- void Renderer::drawQuadInstanced(U32 primitiveCount)
- {
- quadVao.bind();
- glDrawElementsInstanced(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, 0,
- primitiveCount);
- }
- //==============================================================================
- void Renderer::drawQuadMultiple(U times)
- {
- quadVao.bind();
- #if ANKI_GL == ANKI_GL_DESKTOP
- const U max_times = 16;
- Array<GLsizei, max_times> count;
- Array<const GLvoid*, max_times> indices;
- for(U i = 0; i < times; i++)
- {
- count[i] = 2 * 3;
- indices[i] = nullptr;
- }
- glMultiDrawElements(
- GL_TRIANGLES, &count[0], GL_UNSIGNED_SHORT, &indices[0], times);
- #else
- for(U i = 0; i < times; i++)
- {
- glDrawElements(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, 0);
- }
- #endif
- }
- //==============================================================================
- Vec3 Renderer::unproject(const Vec3& windowCoords, const Mat4& modelViewMat,
- const Mat4& projectionMat, const int view[4])
- {
- Mat4 invPm = projectionMat * modelViewMat;
- invPm.invert();
- // the vec is in NDC space meaning: -1<=vec.x<=1 -1<=vec.y<=1 -1<=vec.z<=1
- Vec4 vec;
- vec.x() = (2.0 * (windowCoords.x() - view[0])) / view[2] - 1.0;
- vec.y() = (2.0 * (windowCoords.y() - view[1])) / view[3] - 1.0;
- vec.z() = 2.0 * windowCoords.z() - 1.0;
- vec.w() = 1.0;
- Vec4 final = invPm * vec;
- final /= final.w();
- return Vec3(final);
- }
- //==============================================================================
- void Renderer::calcPlanes(const Vec2& cameraRange, Vec2& planes)
- {
- F32 zNear = cameraRange.x();
- F32 zFar = cameraRange.y();
- F32 opt = zNear - zFar;
- planes.x() = zFar / opt;
- planes.y() = (zFar * zNear) / opt;
- }
- //==============================================================================
- void Renderer::calcLimitsOfNearPlane(const PerspectiveCamera& pcam,
- Vec2& limitsOfNearPlane)
- {
- limitsOfNearPlane.y() = tan(0.5 * pcam.getFovY());
- limitsOfNearPlane.x() = tan(0.5 * pcam.getFovX());
- }
- //==============================================================================
- void Renderer::clearAfterBindingFbo(const GLenum cap)
- {
- if(GlStateCommonSingleton::get().getGpu() == GlStateCommon::GPU_ARM)
- {
- glClear(cap);
- }
- }
- } // end namespace anki
|