void LevelScene::render()
{
    GlRenderer::clearScreen();
    size_t c = 0;

    if(!m_isInit)
        goto renderBlack;

    GlRenderer::setTextureColor(1.0f, 1.0f, 1.0f, 1.0f);

    for(PGE_LevelCamera &cam : m_cameras)
    {
        if(m_numberOfPlayers > 1)
            GlRenderer::setViewport(static_cast<int>(cam.renderX()),
                                    static_cast<int>(cam.renderY()),
                                    static_cast<int>(cam.w()),
                                    static_cast<int>(cam.h()));

        cam.drawBackground();
        double camPosX = cam.posX();
        double camPosY = cam.posY();
        //Size of array with objects catched by camera
        int render_sz = cam.renderObjects_count();
        //Pointer to array with objects catched by camera
        PGE_Phys_Object **render_obj = cam.renderObjects_arr();
        //Index of array with lua-drawn elements
        size_t currentLuaRenderObj = 0;
        //Size of array with lua-drawn elements
        size_t currentLuaRenderSz = luaRenders.size();

        for(int i = 0; i < render_sz; i++)
        {
            switch(render_obj[i]->type)
            {
            case PGE_Phys_Object::LVLBlock:
            case PGE_Phys_Object::LVLBGO:
            case PGE_Phys_Object::LVLNPC:
            case PGE_Phys_Object::LVLPlayer:
            {
                PGE_Phys_Object *obj = render_obj[i];
                //Get Z-index of current element
                long double Z = obj->zIndex();

                //Draw lua-drew elements which are less than current Z-index
                while(currentLuaRenderObj < currentLuaRenderSz)
                {
                    RenderFuncs &r = luaRenders[currentLuaRenderObj];

                    if(r.z_index > Z)
                        break;

                    r.render(camPosX, camPosY);
                    currentLuaRenderObj++;
                }

                //Draw element itself
                obj->render(camPosX, camPosY);
                break;
            }

            default:
                break;
            }
        }

        //Draw elements left after all camera objects are drawn
        while(currentLuaRenderObj < currentLuaRenderSz)
        {
            RenderFuncs &r = luaRenders[currentLuaRenderObj];
            r.render(camPosX, camPosY);
            currentLuaRenderObj++;
        }

        if(PGE_Window::showPhysicsDebug)
        {
            for(int i = 0; i < render_sz; i++)
            {
                PGE_Phys_Object *obj = render_obj[i];
                obj->renderDebug(camPosX, camPosY);

                if(obj->type == PGE_Phys_Object::LVLNPC)
                {
                    auto *npc = dynamic_cast<LVL_Npc *>(obj);
                    for(auto &i : npc->detectors_inarea)
                    {
                        PGE_RectF trapZone = i.trapZone();
                        GlRenderer::renderRect(static_cast<float>(trapZone.x() - camPosX),
                                               static_cast<float>(trapZone.y() - camPosY),
                                               static_cast<float>(trapZone.width()),
                                               static_cast<float>(trapZone.height()),
                                               1.0f, 0.0, 0.0f, 1.0f, false);
                    }
                }
            }
        }

        cam.drawForeground();

        if(m_numberOfPlayers > 1)
            GlRenderer::resetViewport();

        c++;
    }

    //Draw camera separators
    for(c = 1; c < m_cameras.size(); c++)
        GlRenderer::renderRect(0, float(m_cameras[c].h()) * c - 1, m_cameras[c].w(), 2, 0.f, 0.f, 0.f, 1.f);

    if(PGE_Window::showDebugInfo)
    {
        //FontManager::printText(fmt::format_ne("Camera X={0} Y={1}", cam_x, cam_y), 200,10);
        int dpos = 60;
        FontManager::printText(fmt::format_ne("Player J={0} G={1} F={2}; TICK-SUB: {3}\n"
                                           "NPC's: {4}, Active {5}; BLOCKS: {6}",
                                           int(m_debug_player_jumping),
                                           int(m_debug_player_onground),
                                           int(m_debug_player_foots),
                                           uTickf,
                                           m_itemsNpc.size(),
                                           m_npcActive.size(),
                                           m_itemsBlocks.size()), 10, dpos);
        dpos += 35;
        FontManager::printText(fmt::format_ne("Visible objects: {0}", !m_cameras.empty() ? m_cameras[0].renderObjects_count() : 0), 10, dpos);
        dpos += 35;
        FontManager::printText(fmt::format_ne("Delays E={0} R={1} P={2}",
                                           m_debug_event_delay,
                                           m_debug_render_delay,
                                           m_debug_phys_delay), 10, dpos);
        dpos += 35;
        FontManager::printText(fmt::format_ne("Time Real:{0}\nTime Loop:{1}",
                                           debug_TimeReal.elapsed(),
                                           debug_TimeCounted), 10, dpos);
        dpos += 35;

        if(!m_isLevelContinues)
        {
            FontManager::printText(fmt::format_ne("Exit delay {0}, {1}",
                                               m_exitLevelDelay,
                                               uTickf), 10, dpos, FontManager::DefaultRaster, 1.0, 0, 0, 1.0);
            dpos += 35;
        }

        if(m_placingMode)
            FontManager::printText(fmt::format_ne("Placing! {0} X={1} Y={2}",
                                               m_placingMode_item_type,
                                               m_placingMode_renderAt.x(),
                                               m_placingMode_renderAt.y()), 10, 10, FontManager::DefaultRaster);
        else
            FontManager::printText(fmt::format_ne("{0}", PGE_MusPlayer::getTitle()), 10, 10, FontManager::DefaultRaster);
    }

renderBlack:
    {
        if(!m_fader.isNull())
            GlRenderer::renderRect(0.f,
                                   0.f,
                                   static_cast<float>(PGE_Window::Width),
                                   static_cast<float>(PGE_Window::Height),
                                   0.f, 0.f, 0.f,
                                   static_cast<float>(m_fader.fadeRatio()));
    }

    if(m_placingMode)
        drawPlacingItem();
    if(m_loaderIsWorks)
        drawLoader();
    if(m_isPauseMenu)
        m_pauseMenu.render();
    // Flip the syncronious blinker flag
    m_blinkStateFlag = !m_blinkStateFlag;
}