Ogre资源加载流程概述

来源:互联网 发布:高博软件培训中心 编辑:程序博客网 时间:2024/05/22 04:33

Ogre资源加载流程:

ResourceGroupManager   简写为     rgm

 

1)     创建资源组 rgm.createResourceGroup

2)     添加资源组路径 rgm.addResourceLocaltion

3)     初始化资源组

4)     创建场景时资源的加载

5)     删除资源组

 

 

1)     创建资源组

带参数boolglobalPool,是true的话就放在global pool里。False就在local pool

 

2)添加资源组路径

源码:

    voidResourceGroupManager::addResourceLocation(constString&name,

        constString&locType,constString& resGroup,boolrecursive)

    {

        ResourceGroup*grp=getResourceGroup(resGroup);

        if (!grp)

        {

            createResourceGroup(resGroup);

            grp =getResourceGroup(resGroup);

        }

 

       OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME)//lock group mutex

 

        // Get archive

/*为该资源组新增一个ResourceLocation,里面存放archive*/

        Archive*pArch=ArchiveManager::getSingleton().load(name,locType );

        // Add to location list

       ResourceLocation*loc=OGRE_NEW_T(ResourceLocation,MEMCATEGORY_RESOURCE);

       loc->archive=pArch;

       loc->recursive=recursive;

        grp->locationList.push_back(loc);

        // Index resources

        StringVectorPtrvec=pArch->find("*",recursive);

        for(StringVector::iteratorit =vec->begin();it !=vec->end(); ++it )

           //加入到resourceGroup里面的resourceIndexCaseInsensitive[file, archive]

           grp->addToIndex(*it,pArch);

      

       StringUtil::StrStreamTypemsg;

       msg <<"Addedresource location '" <<name<<"' of type '" <<locType

           << "' to resource group '" << resGroup << "'";

       if (recursive)

           msg <<"with recursive option";

       LogManager::getSingleton().logMessage(msg.str());

 

    }

 

 

3)初始化资源组

源码:

       //解析资源脚本

           parseResourceGroupScripts(grp);   

           mCurrentGroup =grp;

           //创建资源,但不加载

       createDeclaredResources(grp);

 

    voidResourceGroupManager::createDeclaredResources(ResourceGroup*grp)

    {

 

       for (ResourceDeclarationList::iteratori =grp->resourceDeclarations.begin();

           i !=grp->resourceDeclarations.end();++i)

       {

           ResourceDeclaration&dcl= *i;

           // Retrieve the appropriate manager

           ResourceManager*mgr=_getResourceManager(dcl.resourceType);

           //创建资源

           ResourcePtrres=mgr->create(dcl.resourceName,grp->name,

                dcl.loader !=0,dcl.loader,&dcl.parameters);

           // 加到resourceGrouploadResourceOrderMap里面

           //有个问题:上面创建的时候会调

           ResourcePtrResourceManager::create(const String& name, const String& group,

                                          boolisManual, ManualResourceLoader* loader, const NameValuePairList* params)

    {

       // Callcreation implementation

       ResourcePtrret = ResourcePtr(

           createImpl(name, getNextHandle(), group, isManual, loader, params));

        if (params)

           ret->setParameterList(*params);

 

       addImpl(ret);

       // Tellresource group manager

       ResourceGroupManager::getSingleton()._notifyResourceCreated(ret);    这句会通过 rgm.addCreatedResource加到对应resourceGrouploadResourceOrderMap里面,下面又添加了一次

       return ret;

    }

           ResourceGroup::LoadResourceOrderMap::iteratorli =

              grp->loadResourceOrderMap.find(mgr->getLoadingOrder());

           LoadUnloadResourceList*loadList;

           if (li ==grp->loadResourceOrderMap.end())

           {

              loadList =OGRE_NEW_T(LoadUnloadResourceList,MEMCATEGORY_RESOURCE)();

              grp->loadResourceOrderMap[mgr->getLoadingOrder()]=loadList;

           }

           else

           {

              loadList =li->second;

           }

           loadList->push_back(res);

 

       }

 

    }

 

 

4)场景创建时资源的加载

    以mesh为例:

    sceneManger:: createMovableObject()

调用MovableObjectFactory::createInstance()

调用EntityFactory::createInstanceImpl()

调用

MeshManager::getSingleton().load(

                      ni->second,

                      // autodetectgroup location

                      groupName );

                  调用

                     MeshManager::createOrRetrieve()通过ResourceManager::getByName()来获取是否已经创建(查询mResourcesWithGroup只要是通过Resourcemanager::create过的都能找到

                     找到后调用meshPtr->load()调用       mFreshFromDisk=ResourceGroupManager::getSingleton().openResource(mName,mGroup,true,this); 加载真实的mesh文件 

Mesh文件是在resourcegroupresourceIndexCaseInsensitive里面查找的(如果找不到会整个目录遍历,参见ogreResourceGroupManager.cpp719行),而该结构体是在rgm.addresourcelocation里面完成初始化的

 

5)资源卸载

    rgm.destroyResourceGroup()

        unloadResourceGroup(name,false);//卸载resourceGrouploadResourceOrderMap里面所有资源

       dropGroupContents(grp);           //删除resourceGrouploadResourceOrderMap里面所有资源,调用resourcemanagerremove

       deleteGroup(grp);                 //删除资源组和路径

         mResourceGroupMap.erase(mResourceGroupMap.find(name));

 

特别情况的处理:

    reourceGroup已经建立并且initialized,此时要在该目录下面加新的mesh或者纹理贴图进去:

1) 把文件拷贝进去

2) Rgm.removeResourceLocaltion()然后在在add一次,此时resourceGroup的resourceIndexCaseInsensitive已经包含了最新的文件列表  (可选,理由见第4条)

3) Resourcemanager::create()  创建实例,这样会通知rgm更改相应的redourceGrouploadResourceOrderMap,保证卸载时能够安全删除

4) ResourcePtr->load()即可