void DeferredContainer::draw() const {
    //"The Screen". It may not be actually the screen since a upper container might be postprocessing
    const RenderTargetBase* screen = RenderTargetBase::getCurrent();

    GL_ASSERT(glEnable(GL_DEPTH_TEST));
    GL_ASSERT(glDisable(GL_BLEND));

    //Deferred pass
    Debugger::pushMark("Deferred Pass", "Time spent rendering geometry to the g-buffer");
    drawMode = Deferred;
    RenderTargetBase::bind(gBuffer);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT));
    ContainerObject::draw();
    Debugger::popMark(); //deferred

    //Shadowmap pass
    Debugger::pushMark("Shadowmap Pass", "Time spent rendering geometry to the layered shadowmap");
    glEnable(GL_DEPTH_CLAMP);
    drawMode = ShadowMap;
    RenderTargetBase::bind(sunTarget);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT));
    ContainerObject::draw();
    glDisable(GL_DEPTH_CLAMP);
    Debugger::popMark(); //shadow

    //Transparent shadowmap pass
    Debugger::pushMark("Transparent ShadowMap Pass", "Time spent rendering transparent geometry to the layered shadowmap");
    glEnable(GL_DEPTH_CLAMP);
    drawMode = TransShadowMap;
    RenderTargetBase::bind(sunTargetTrans);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT));
    ContainerObject::draw();
    glDisable(GL_DEPTH_CLAMP);
    Debugger::popMark(); //transparent shadow

    Debugger::pushMark("Light Pass", "Time spent rendering deferred lights");
    //bind output texture (screen)
    RenderTargetBase::bind(screen);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT));

    //Light pass
    GL_ASSERT(glEnable(GL_BLEND));
    GL_ASSERT(glBlendFunc(GL_ONE, GL_ONE)); //additive
    GL_ASSERT(glDepthMask(GL_FALSE));
    GL_ASSERT(glDepthFunc(GL_ALWAYS));
    drawMode = Light;
    ContainerObject::draw();
    Debugger::popMark(); //lights

    //Ambient+Visibility pass
    Debugger::pushMark("Ambient+Visibility Pass", "Time spent rendering ambient light and sunlight contribution to the scene");
    GL_ASSERT(glDepthMask(GL_TRUE));
    const Camera* cam = (Camera*)getGame()->getObjectByName("playerCam");
    Sun* sun = (Sun*)getGame()->getObjectByName("sun");
    glm::mat4 biasMatrix( //gets coords from [-1..1] to [0..1]
                          0.5, 0.0, 0.0, 0.0,
                          0.0, 0.5, 0.0, 0.0,
                          0.0, 0.0, 0.5, 0.0,
                          0.5, 0.5, 0.5, 1.0
                          );
    //compute each of the cascaded cameras's matrices
    std::vector<mat4f> depthMVP(NUM_SUN_CASCADES);
    for(int i = 0; i < NUM_SUN_CASCADES; ++i)
        depthMVP[i] = biasMatrix*(sun->getVPMatrices()[i]*fullTransform);
    Programs.get("ambientPass").uniform("MVP")->set(mat4f(1.0f));
    Programs.get("ambientPass").uniform("camMV")->set(cam->getView()*fullTransform);
    Programs.get("ambientPass").uniform("color0")->set(getColor0());
    Programs.get("ambientPass").uniform("color1")->set(getColor1());
    Programs.get("ambientPass").uniform("invResolution")->set(vec2f(1.0f/screen->getSize().x, 1.0f/screen->getSize().y));
    Programs.get("ambientPass").uniform("invCamProj")->set(glm::inverse(cam->projection));
    Programs.get("ambientPass").uniform("invCamView")->set(glm::inverse(cam->getView()));
    Programs.get("ambientPass").uniform("lightDir")->set(sun->getCam(0)->getForward());
    Programs.get("ambientPass").uniform("worldsize")->set(WORLDSIZE);
    Programs.get("ambientPass").uniform("depthMVP")->set(depthMVP);
    Programs.get("ambientPass").uniform("depthPlanes")->set(sun->getDepthPlanes());
    Programs.get("ambientPass").uniform("depth")->set(gBuffer.getTexture(RenderTargetBase::DEPTH));
    Programs.get("ambientPass").uniform("sunDepth")->set(sunTarget.getTexture(RenderTargetBase::DEPTH));
    Programs.get("ambientPass").uniform("sunDepthTrans")->set(sunTargetTrans.getTexture(RenderTargetBase::DEPTH));
    quad->draw(Programs.get("ambientPass"));
    Debugger::popMark(); //ambient+shadowmap

    //Forward pass
    Debugger::pushMark("Forward Pass", "Time spent rendering forward-render stuff");
    GL_ASSERT(glDepthMask(GL_TRUE));
    GL_ASSERT(glDepthFunc(GL_LEQUAL));
    GL_ASSERT(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); //forward rendering blending
    drawMode = Forward;
    ContainerObject::draw();
    Debugger::popMark();
}
void MultiColoredQuadUIDrawObject::draw(Graphics* const Graphics, Real32 Opacity) const
{
	Graphics->drawQuad(getPoint1(),getPoint2(),getPoint3(),getPoint4(),
                       getColor1(), getColor2(), getColor3(), getColor4(),
                       getOpacity()*Opacity);
}