예제 #1
0
// ----------------------------------------------------------------------------
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);
    }
}
예제 #2
0
 /** 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();
}
예제 #3
0
// ----------------------------------------------------------------------------
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);
    }
}
예제 #4
0
 /** 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)
}