Ogre实现场景动态装载卸载

经常玩日本游戏的朋友们应该都知道。日本RPG中经常有一些场景切换的画面。比如在角色走动过程中,突然进入战斗状态,他会先把先前的场景渲染成一张图片,然后移开这张图片,在渲染另一个场景,譬如是战斗场景。

最近在休闲网络游戏时,也碰到一个这样的需求。就是在一局游戏中动态的切换场景。

这个项目时间比较紧迫,场景直接用了解析OFusion的OSM文件来做。但是我遇到一些问题是OfusionLoader这个东西,只有装载没有卸载。如果这样的话,就很难满足项目中的需求。(就算没有这个需求,卸载场景还是需要做的)

好在并不是太困难,只要按照OFusion的状态方式,把他所装载的东西都记录下来就可以了。

比如我先把装载的场景中的状态的静态模型都记录到一个容器中

程序代码 程序代码
void OSMScene::createEntities(TiXmlElement* pEntityNode, Ogre::SceneNode* pSceneRoot)
{
    // Iterate all meshes, creating them.
    for (TiXmlElement* pMeshElem = pEntityNode->FirstChildElement();
            pMeshElem != 0; pMeshElem = pMeshElem->NextSiblingElement())
    {
        // Ogre could cast an exception, in which case we just try to
        // continue reading the other meshes
        try
        {
            const char *pszName = pMeshElem->Attribute("name");
            const char *pszFileName = pMeshElem->Attribute("filename");

            // try to create the mesh
            Entity *pEntity = mSceneMgr->createEntity(pszName, pszFileName);
            
            if(pEntity==0) continue;

            // Check if the object should cast shadows
            const char *pszCastShadows=pMeshElem->Attribute("CastShadows");
            if(pszCastShadows && stricmp(pszCastShadows, "no")==0)
                pEntity->setCastShadows(false);    
            else
                pEntity->setCastShadows(true);    

            // Create node with full information
            SceneNode *pObjNode=createNode(pMeshElem, pSceneRoot);


            // Attach the mesh entity to node
            pObjNode->attachObject(pEntity);

            StaticModel * staticModel = new StaticModel();
            staticModel->mEntity    = pEntity;
            staticModel->mSceneNode = pObjNode;
            mStaticModelList.push_back(staticModel);

            // Notify
            if(mCallbacks)
                mCallbacks->OnEntityCreate(pEntity, pMeshElem);

            // Add to entity list
            mEntities.push_back(pEntity);
        } catch(...)
        {
            continue;
        }            
    }    
}



然后再清理场景之间清理掉他们

程序代码 程序代码
// Delete all entity
void OSMScene::deleteEntities(void)
{
    std::vector<StaticModel * >::iterator StaticModelIter;
    for(StaticModelIter = mStaticModelList.begin(); StaticModelIter != mStaticModelList.end(); ++StaticModelIter)
    {
        Ogre::Entity      * pEntity    = (*StaticModelIter)->mEntity;
        Ogre::SceneNode   * pSceneNode = (*StaticModelIter)->mSceneNode;
        pSceneNode->detachObject(pEntity);
        mSceneMgr->destroySceneNode(pSceneNode);
        mSceneMgr->destroyEntity(pEntity);
        delete *StaticModelIter;
    }
    mStaticModelList.clear();

}



其他象摄像机,灯光都按照这样的方法装载、卸载掉。

程序代码 程序代码
最后清理场景
bool OSMScene::destroyScene()
{
    try
    {
        deleteEntities();
                                deleteLight();
                                deleteCamera();
.............................................................
        return true;
    }
    catch(...)
    {
        LogManager::getSingleton().logMessage("Error");    
    }

    return false;
}



当然由于OFusion也沿用了Ogre的文件管理系统,因此在加载前他把自己的资源目录添加到Ogre的资源配置文件中去了,在卸载的时候我们也需要删除它们,防止那个资源目录爆炸式的增加

程序代码 程序代码
void OSMScene::undeclareResources(void)
{
    if(!mXMLDoc.isNull())
    {

        TiXmlElement* rootElem = mXMLDoc->RootElement();

        try
        {
            // Get mesh filename from entities
            TiXmlElement *pMeshNode = rootElem->FirstChildElement("entities");
            if(pMeshNode)
            {
                // Iterate all meshes, creating them.
                for (TiXmlElement* pMeshElem = pMeshNode->FirstChildElement();
                pMeshElem != 0; pMeshElem = pMeshElem->NextSiblingElement())
                {    
                    // Declare mesh resource
                    const char *pszFileName = pMeshElem->Attribute("filename");    
                    ResourceGroupManager::getSingleton().undeclareResource(pszFileName, "Mesh");
                }
            }
        } catch(...)
        {
        }

    }

}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值