void eDeferredRenderer::_showGeometryBuffer(eTexture2d *target, const eRect &area) const
{
    const eInt w = area.getWidth();
    const eInt h = area.getHeight();

    eGfx->freshRenderState().targets[0] = target;

    renderQuad(eRect(  0, h/3, w/2,     h), area.getSize(), m_rtShadow);    // top left
    renderQuad(eRect(w/2, h/3,   w,     h), area.getSize(), m_texDistMap);  // top right
    renderQuad(eRect(  0, h/3, w/2, 2*h/3), area.getSize(), m_rtSpecular);  // middle left
    renderQuad(eRect(w/2, h/3,   w, 2*h/3), area.getSize(), m_rtDiffuse);   // middle right
    renderQuad(eRect(  0,   0, w/2,   h/3), area.getSize(), m_rtNormals);   // bottom left
    renderQuad(eRect(w/2,   0,   w,   h/3), area.getSize(), m_rtPosition);  // bottom right
}
void eDeferredRenderer::_renderAmbientPass(eTexture2d *target, eTexture2d *depthTarget, const eScene &scene, const eRect &area)
{
    // calculate the ambient color
    eColor ambient;
    for (eU32 i=0; i<scene.getLightCount(); i++)
        ambient += scene.getLight(i).getAmbient();

    // render the ambient light
    static eConstBuffer<eVector4, eST_PS> cb;
    cb.data = ambient;

    eRenderState &rs = eGfx->freshRenderState();
    rs.targets[0] = target;
	rs.depthTarget = depthTarget;
    rs.ps = m_psDefAmbient;
    rs.constBufs[eCBI_PASS_AMBIENT] = &cb;
    rs.textures[0] = m_rtDiffuse;
	rs.textures[3] = m_rtPosition;
    rs.textures[4] = m_rtEnvironment;
    rs.texFlags[0] = eTMF_CLAMP|eTMF_NEAREST;
	rs.texFlags[3] = eTMF_CLAMP|eTMF_NEAREST;
    rs.texFlags[4] = eTMF_CLAMP|eTMF_NEAREST;

    eGfx->clear(eCM_COLOR, eCOL_YELLOW);
    renderQuad(area, area.getSize(), nullptr);
}
void eDeferredRenderer::_renderLightPass(eTexture2d *target, eTexture2d *depthTarget, const eScene &scene, const eCamera &cam, const eRect &area)
{
    for (eU32 i=0; i<scene.getLightCount(); i++)
    {
        const eLight &light = scene.getLight(i);
        if (light.activateScissor(area.getSize(), cam))
        {
            // create shadow map for light
#ifndef eCFG_NO_ENGINE_DEFERRED_SHADOWS
            _renderLightDistance(scene, light);
            _renderShadowMap(cam, light, depthTarget);
#endif

            // perform deferred lighting+shadowing
            eRenderState &rs = eGfx->freshRenderState();
            rs.targets[0] = target;
			rs.depthTarget = depthTarget;
            rs.textures[0] = m_rtDiffuse;
            rs.textures[1] = m_rtNormals;
            rs.textures[2] = m_rtSpecular;
            rs.textures[3] = m_rtPosition;
            rs.textures[4] = m_rtShadow;
            rs.texFlags[0] = eTMF_CLAMP|eTMF_NEAREST;
            rs.texFlags[1] = eTMF_CLAMP|eTMF_NEAREST;
            rs.texFlags[2] = eTMF_CLAMP|eTMF_NEAREST;
            rs.texFlags[3] = eTMF_CLAMP|eTMF_NEAREST;
            rs.texFlags[4] = eTMF_BILINEAR;
            rs.blending = eTRUE;
            rs.blendSrc = eBM_ONE;
            rs.blendDst = eBM_ONE;
            rs.ps = m_psDefLight;
            rs.vs = m_vsQuad;

            light.activate(cam.getViewMatrix());
            renderQuad(area, area.getSize());
        }
    }
}
void eDeferredRenderer::_renderAlphaLightPass(eTexture2d *target, eTexture2d *depthTarget, const eScene &scene, const eCamera &cam, const eRect &area)
{
    eRenderState &rs = eGfx->freshRenderState();
    rs.targets[0] = target;
	rs.depthTarget = depthTarget;
    rs.viewport.set(0, 0, m_rtNormals->width, m_rtNormals->height);

    for (eU32 i=0; i<scene.getLightCount(); i++)
    {
        const eLight &light = scene.getLight(i);
        if (light.activateScissor(area.getSize(), cam))
        {
            light.activate(cam.getViewMatrix());
            m_allJobs.render(cam, eRJW_ALPHA_ON|eRJW_LIGHTED_ON|eRJW_SHADOWS_BOTH);
        }
    }
}