void PGE_LevelCamera::sortElements() { if(objects_to_render.size()<=1) return; //Nothing to sort! QStack<int> beg; QStack<int> end; PGE_Phys_Object* piv; int i=0, L, R, swapv; beg.push_back(0); end.push_back(objects_to_render.size()); while (i>=0) { L=beg[i]; R=end[i]-1; if (L<R) { piv=objects_to_render[L]; while (L<R) { while ((objects_to_render[R]->zIndex()>=piv->zIndex()) && (L<R)) R--; if (L<R) objects_to_render[L++]=objects_to_render[R]; while ((objects_to_render[L]->zIndex()<=piv->zIndex()) && (L<R)) L++; if (L<R) objects_to_render[R--]=objects_to_render[L]; } objects_to_render[L]=piv; beg.push_back(L+1); end.push_back(end[i]); end[i++]=(L); if((end[i]-beg[i]) > (end[i-1]-beg[i-1])) { swapv=beg[i]; beg[i]=beg[i-1]; beg[i-1]=swapv; swapv=end[i]; end[i]=end[i-1]; end[i-1]=swapv; } } else { i--; beg.pop_back(); end.pop_back(); } } }
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; }