Esempio n. 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);
    }
}
Esempio n. 2
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);
    }
}
Esempio n. 3
0
// ----------------------------------------------------------------------------
void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
                                std::vector<scene::ISceneNode *> *ImmediateDraw,
                                const scene::ICameraSceneNode *cam,
                                ShadowMatrices& shadow_matrices)
{
    STKMeshCommon* node = dynamic_cast<STKMeshCommon*>(Node);
    if (!node)
        return;
    node->updateNoGL();
    m_deferred_update.push_back(node);

    if (node->isImmediateDraw())
    {
        ImmediateDraw->push_back(Node);
        return;
    }

    bool culled_for_cams[6] = { true, true, true, true, true, true };
    culled_for_cams[0] = isCulledPrecise(cam, Node,
        irr_driver->getBoundingBoxesViz());

    if (UserConfigParams::m_gi && !shadow_matrices.isRSMMapAvail())
    {
        culled_for_cams[1] = isCulledPrecise(shadow_matrices.getSunCam(), Node);
    }

    if (CVS->isShadowEnabled())
    {
        for (unsigned i = 0; i < 4; i++)
        {
            culled_for_cams[i + 2] =
                isCulledPrecise(shadow_matrices.getShadowCamNodes()[i], Node);
        }
    }

    // Transparent
    if (World::getWorld() && World::getWorld()->isFogEnabled())
    {
        const Track * const track = World::getWorld()->getTrack();

        // Todo : put everything in a ubo
        const float fogmax = track->getFogMax();
        const float startH = track->getFogStartHeight();
        const float endH = track->getFogEndHeight();
        const float start = track->getFogStart();
        const float end = track->getFogEnd();
        const video::SColor tmpcol = track->getFogColor();

        video::SColorf col(tmpcol.getRed() / 255.0f,
            tmpcol.getGreen() / 255.0f,
            tmpcol.getBlue() / 255.0f);

        for (GLMesh *mesh : node->TransparentMesh[TM_DEFAULT])
            pushVector(ListBlendTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans,
            fogmax, startH, endH, start, end, col);
        for (GLMesh *mesh : node->TransparentMesh[TM_ADDITIVE])
            pushVector(ListAdditiveTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans,
            fogmax, startH, endH, start, end, col);
    }
    else
    {
        for (GLMesh *mesh : node->TransparentMesh[TM_DEFAULT])
            pushVector(ListBlendTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, 1.0f);
        for (GLMesh *mesh : node->TransparentMesh[TM_ADDITIVE])
            pushVector(ListAdditiveTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, 1.0f);
    }

    // Use sun color to determine custom alpha for ghost karts
    float custom_alpha = 1.0f;
    if (World::getWorld())
    {
        const video::SColor& c = World::getWorld()->getTrack()->getSunColor();
        float y = 0.2126f * c.getRed() + 0.7152f * c.getGreen() + 0.0722f * c.getBlue();
        custom_alpha = y > 128.0f ? 0.5f : 0.35f;
    }

    for (GLMesh *mesh : node->TransparentMesh[TM_TRANSLUCENT_STD])
        pushVector(ListTranslucentStandard::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, custom_alpha);
    for (GLMesh *mesh : node->TransparentMesh[TM_TRANSLUCENT_TAN])
        pushVector(ListTranslucentTangents::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, custom_alpha);
    for (GLMesh *mesh : node->TransparentMesh[TM_TRANSLUCENT_2TC])
        pushVector(ListTranslucent2TCoords::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, custom_alpha);
    for (GLMesh *mesh : node->TransparentMesh[TM_DISPLACEMENT])
        pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());

    if (!culled_for_cams[0])
    {
        for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
        {
            if (CVS->supportsIndirectInstancingRendering())
            {
                for (GLMesh *mesh : node->MeshSolidMaterial[Mat])
                {
                    if (node->glow())
                    {
                        m_glow_pass_mesh[mesh->mb].m_mesh = mesh;
                        m_glow_pass_mesh[mesh->mb].m_instance_settings
                            .emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f));
                    }
                    if (Mat == Material::SHADERTYPE_SPLATTING)
                    {
                        // Notice: splatting will be drawn using non-instanced shader only
                        // It's only used one place (in overworld) and may be removed eventually
                        core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
                        ModelMatrix.getInverse(InvModelMatrix);
                        ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix);
                    }
                    else
                    {
                        // Only take render info into account if the node is not static (animated)
                        // So they can have different animation
                        std::pair<scene::IMeshBuffer*, RenderInfo*> mesh_render_info(mesh->mb,
                            dynamic_cast<STKMeshSceneNode*>(Node) == NULL ? mesh->m_render_info : NULL);
                        m_solid_pass_mesh[Mat][mesh_render_info].m_mesh = mesh;
                        m_solid_pass_mesh[Mat][mesh_render_info].m_instance_settings.emplace_back(Node, mesh->texture_trans,
                            (mesh->m_render_info && mesh->m_material ?
                            core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
                            core::vector2df(0.0f, 0.0f)));
                    }
                }
            }
            else
            {
                core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
                ModelMatrix.getInverse(InvModelMatrix);

                for (GLMesh *mesh : node->MeshSolidMaterial[Mat])
                {
                    switch (Mat)
                    {
                    case Material::SHADERTYPE_SOLID:
                        ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
                            (mesh->m_render_info && mesh->m_material ?
                            core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
                            core::vector2df(0.0f, 0.0f)));
                        break;
                    case Material::SHADERTYPE_ALPHA_TEST:
                        ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
                            (mesh->m_render_info && mesh->m_material ?
                            core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
                            core::vector2df(0.0f, 0.0f)));
                        break;
                    case Material::SHADERTYPE_NORMAL_MAP:
                        ListMatNormalMap::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
                            (mesh->m_render_info && mesh->m_material ?
                            core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
                            core::vector2df(0.0f, 0.0f)));
                        break;
                    case Material::SHADERTYPE_DETAIL_MAP:
                        ListMatDetails::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans);
                        break;
                    case Material::SHADERTYPE_SOLID_UNLIT:
                        ListMatUnlit::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans);
                        break;
                    case Material::SHADERTYPE_SPHERE_MAP:
                        ListMatSphereMap::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans);
                        break;
                    case Material::SHADERTYPE_SPLATTING:
                        ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix);
                        break;
                    case Material::SHADERTYPE_VEGETATION:
                        ListMatGrass::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir,
                            (mesh->m_render_info && mesh->m_material ?
                            core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
                            core::vector2df(0.0f, 0.0f)));
                        break;
                    case Material::SHADERTYPE_ALPHA_BLEND:
                        break;
                    case Material::SHADERTYPE_ADDITIVE:
                        break;
                    case Material::SHADERTYPE_WATER:
                        break;
                    default:
                        Log::warn("DrawCalls", "Unknown material type: %d", Mat);
                    }
                }
            }
        }
    }
    if (!CVS->isShadowEnabled())
        return;
    for (unsigned cascade = 0; cascade < 4; ++cascade)
    {
        if (culled_for_cams[cascade + 2])
            continue;
        for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
        {
            if (CVS->supportsIndirectInstancingRendering())
            {
                for (GLMesh *mesh : node->MeshSolidMaterial[Mat])
                {
                    m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_mesh = mesh;
                    m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_instance_settings
                        .emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f));
                }
            }
            else
            {
                core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
                ModelMatrix.getInverse(InvModelMatrix);

                for (GLMesh *mesh : node->MeshSolidMaterial[Mat])
                {
                    switch (Mat)
                    {
                    case Material::SHADERTYPE_SOLID:
                        ListMatDefault::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
                        break;
                    case Material::SHADERTYPE_ALPHA_TEST:
                        ListMatAlphaRef::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
                        break;
                    case Material::SHADERTYPE_NORMAL_MAP:
                        ListMatNormalMap::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
                        break;
                    case Material::SHADERTYPE_DETAIL_MAP:
                        ListMatDetails::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans);
                        break;
                    case Material::SHADERTYPE_SOLID_UNLIT:
                        ListMatUnlit::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans);
                        break;
                    case Material::SHADERTYPE_SPHERE_MAP:
                        ListMatSphereMap::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans);
                        break;
                    case Material::SHADERTYPE_SPLATTING:
                        ListMatSplatting::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix);
                        break;
                    case Material::SHADERTYPE_VEGETATION:
                        ListMatGrass::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir,
                            (mesh->m_render_info && mesh->m_material ?
                            core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
                            core::vector2df(0.0f, 0.0f)));
                    case Material::SHADERTYPE_ALPHA_BLEND:
                        break;
                    case Material::SHADERTYPE_ADDITIVE:
                        break;
                    case Material::SHADERTYPE_WATER:
                        break;
                    default:
                        Log::warn("DrawCalls", "Unknown material type: %d", Mat);
                    }
                }
            }
        }
    }
    if (!UserConfigParams::m_gi || shadow_matrices.isRSMMapAvail())
        return;
    if (!culled_for_cams[1])
    {
        for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
        {
            if (CVS->supportsIndirectInstancingRendering())
            {
                for (GLMesh *mesh : node->MeshSolidMaterial[Mat])
                {
                    if (Mat == Material::SHADERTYPE_SPLATTING)
                    {
                        core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
                        ModelMatrix.getInverse(InvModelMatrix);
                        ListMatSplatting::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix);
                    }
                    else
                    {
                        m_reflective_shadow_map_mesh[Mat][mesh->mb].m_mesh = mesh;
                        m_reflective_shadow_map_mesh[Mat][mesh->mb].m_instance_settings
                            .emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f));
                    }
                }
            }
            else
            {
                core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix;
                ModelMatrix.getInverse(InvModelMatrix);

                for (GLMesh *mesh : node->MeshSolidMaterial[Mat])
                {
                    switch (Mat)
                    {
                    case Material::SHADERTYPE_SOLID:
                        ListMatDefault::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
                        break;
                    case Material::SHADERTYPE_ALPHA_TEST:
                        ListMatAlphaRef::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
                        break;
                    case Material::SHADERTYPE_NORMAL_MAP:
                        ListMatNormalMap::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
                        break;
                    case Material::SHADERTYPE_DETAIL_MAP:
                        ListMatDetails::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans);
                        break;
                    case Material::SHADERTYPE_SOLID_UNLIT:
                        ListMatUnlit::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans);
                        break;
                    case Material::SHADERTYPE_SPHERE_MAP:
                        ListMatSphereMap::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans);
                        break;
                    case Material::SHADERTYPE_SPLATTING:
                        ListMatSplatting::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix);
                        break;
                    case Material::SHADERTYPE_VEGETATION:
                        ListMatGrass::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir,
                            (mesh->m_render_info && mesh->m_material ?
                            core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
                            core::vector2df(0.0f, 0.0f)));
                        break;
                    case Material::SHADERTYPE_ALPHA_BLEND:
                        break;
                    case Material::SHADERTYPE_ADDITIVE:
                        break;
                    case Material::SHADERTYPE_WATER:
                        break;
                    default:
                        Log::warn("DrawCalls", "Unknown material type: %d", Mat);
                    }
                }
            }
        }
    }
}