Ogre实现场景动态装载卸载

来源:互联网 发布:阿里云服务器默认账号 编辑:程序博客网 时间:2024/05/20 04:49

常玩日本游戏的朋友们应该都知道。日本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(...)
         {
         }

     }

}


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wangwang123654/archive/2009/12/10/4977800.aspx