// ---------------------------------------------------------------------------- void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List, std::vector<scene::ISceneNode *> *ImmediateDraw, const scene::ICameraSceneNode *cam, ShadowMatrices& shadow_matrices) { core::list<scene::ISceneNode*>::Iterator I = List.begin(), E = List.end(); for (; I != E; ++I) { if (LODNode *node = dynamic_cast<LODNode *>(*I)) node->updateVisibility(); (*I)->updateAbsolutePosition(); if (!(*I)->isVisible()) continue; if (ParticleSystemProxy *node = dynamic_cast<ParticleSystemProxy *>(*I)) { if (!isCulledPrecise(cam, *I)) m_particles_list.push_back(node); continue; } if (STKBillboard *node = dynamic_cast<STKBillboard *>(*I)) { if (!isCulledPrecise(cam, *I)) m_billboard_list.push_back(node); continue; } handleSTKCommon((*I), ImmediateDraw, cam, shadow_matrices); parseSceneManager((*I)->getChildren(), ImmediateDraw, cam, shadow_matrices); } }
/** Prepare draw calls before scene rendering */ void DrawCalls::prepareDrawCalls(scene::ICameraSceneNode *camnode) { CPUParticleManager::getInstance()->reset(); TextBillboardDrawer::reset(); PROFILER_PUSH_CPU_MARKER("- culling", 0xFF, 0xFF, 0x0); SP::prepareDrawCalls(); parseSceneManager( irr_driver->getSceneManager()->getRootSceneNode()->getChildren(), camnode); SP::handleDynamicDrawCall(); SP::updateModelMatrix(); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("- cpu particle generation", 0x2F, 0x1F, 0x11); CPUParticleManager::getInstance()->generateAll(); PROFILER_POP_CPU_MARKER(); // Add a 1 s timeout if (m_sync != 0) { PROFILER_PUSH_CPU_MARKER("- Sync Stall", 0xFF, 0x0, 0x0); GLenum reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0); if (reason != GL_ALREADY_SIGNALED) { do { reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000); } while (reason == GL_TIMEOUT_EXPIRED); } glDeleteSync(m_sync); m_sync = 0; PROFILER_POP_CPU_MARKER(); } PROFILER_PUSH_CPU_MARKER("- particle and text billboard upload", 0x3F, 0x03, 0x61); CPUParticleManager::getInstance()->uploadAll(); TextBillboardDrawer::updateAll(); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("- SP::upload instance and skinning matrices", 0xFF, 0x0, 0xFF); SP::uploadAll(); PROFILER_POP_CPU_MARKER(); }
// ---------------------------------------------------------------------------- void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List, const scene::ICameraSceneNode *cam) { core::list<scene::ISceneNode*>::Iterator I = List.begin(), E = List.end(); for (; I != E; ++I) { if (LODNode *node = dynamic_cast<LODNode *>(*I)) { node->updateVisibility(); } (*I)->updateAbsolutePosition(); if (!(*I)->isVisible()) continue; if (STKParticle *node = dynamic_cast<STKParticle*>(*I)) { if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz())) CPUParticleManager::getInstance()->addParticleNode(node); continue; } if (scene::IBillboardSceneNode *node = dynamic_cast<scene::IBillboardSceneNode*>(*I)) { if (!isCulledPrecise(cam, *I)) CPUParticleManager::getInstance()->addBillboardNode(node); continue; } if (STKTextBillboard *tb = dynamic_cast<STKTextBillboard*>(*I)) { if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz())) TextBillboardDrawer::addTextBillboard(tb); continue; } SP::SPMeshNode* node = dynamic_cast<SP::SPMeshNode*>(*I); if (node) { SP::addObject(node); } parseSceneManager((*I)->getChildren(), cam); } }
/** Prepare draw calls before scene rendering * \param[out] solid_poly_count Total number of polygons in objects * that will be rendered in this frame * \param[out] shadow_poly_count Total number of polygons for shadow * (rendered this frame) */ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICameraSceneNode *camnode, unsigned &solid_poly_count, unsigned &shadow_poly_count) { m_wind_dir = getWindDir(); clearLists(); for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat) { m_solid_pass_mesh[Mat].clear(); m_reflective_shadow_map_mesh[Mat].clear(); for (unsigned i = 0; i < 4; i++) m_shadow_pass_mesh[i * Material::SHADERTYPE_COUNT + Mat].clear(); } m_glow_pass_mesh.clear(); m_deferred_update.clear(); PROFILER_PUSH_CPU_MARKER("- culling", 0xFF, 0xFF, 0x0); parseSceneManager( irr_driver->getSceneManager()->getRootSceneNode()->getChildren(), &m_immediate_draw_list, camnode, shadow_matrices); PROFILER_POP_CPU_MARKER(); // Add a 1 s timeout if (!m_sync) m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); PROFILER_PUSH_CPU_MARKER("- Sync Stall", 0xFF, 0x0, 0x0); GLenum reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0); if (reason != GL_ALREADY_SIGNALED) { do { reason = glClientWaitSync(m_sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000); } while (reason == GL_TIMEOUT_EXPIRED); } glDeleteSync(m_sync); PROFILER_POP_CPU_MARKER(); /* switch (reason) { case GL_ALREADY_SIGNALED: printf("Already Signaled\n"); break; case GL_TIMEOUT_EXPIRED: printf("Timeout Expired\n"); break; case GL_CONDITION_SATISFIED: printf("Condition Satisfied\n"); break; case GL_WAIT_FAILED: printf("Wait Failed\n"); break; }*/ PROFILER_PUSH_CPU_MARKER("- Animations/Buffer upload", 0x0, 0x0, 0x0); for (unsigned i = 0; i < m_deferred_update.size(); i++) m_deferred_update[i]->updateGL(); PROFILER_POP_CPU_MARKER(); if (!CVS->supportsIndirectInstancingRendering()) return; #if !defined(USE_GLES2) int enableOpenMP = 0; if (CVS->supportsAsyncInstanceUpload()) enableOpenMP = 1; PROFILER_PUSH_CPU_MARKER("- Draw Command upload", 0xFF, 0x0, 0xFF); #pragma omp parallel sections if(enableOpenMP) { #pragma omp section { m_solid_cmd_buffer->fill(m_solid_pass_mesh); } #pragma omp section { m_glow_cmd_buffer->fill(&m_glow_pass_mesh); } #pragma omp section { irr_driver->setPhase(SHADOW_PASS); m_shadow_cmd_buffer->fill(m_shadow_pass_mesh); } #pragma omp section if (!shadow_matrices.isRSMMapAvail()) { m_reflective_shadow_map_cmd_buffer->fill(m_reflective_shadow_map_mesh); } } PROFILER_POP_CPU_MARKER(); solid_poly_count = m_solid_cmd_buffer->getPolyCount(); shadow_poly_count = m_shadow_cmd_buffer->getPolyCount(); if (CVS->supportsAsyncInstanceUpload()) glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT); #endif // !defined(USE_GLES2) }