zoukankan      html  css  js  c++  java
  • [转]OGRE资源的四种状态

    未定义
        游戏程序启动时所有资源的默认状态,资源未被索引,所以OGRE不知道它们的存在。
    已声明
        资源已被索引,OGRE已经知道这些资源的存在,但它们还没被初始化。
        (平时我们读取了资源配置文件之后,资源就进入了这种状态。)
    未载入
        资源已被初始化——被初始化的资源都生成了一个分别对它们的引用(这些引用会占用小部分内存),但资源还没被载入到内存。
        p.s.:如果某个资源有一个脚本,则脚本也已被解析完毕。
        (平时我们调用“ResourceGroupManager::getSingleton().initialiseResourceGroup("General");”函数后,之前被索引的资源就进入未载入状态。)
    已载入
        资源被激活,资源数据存在于内存中,可以被游戏程序直接调用了。(如果游戏程序调用未载入的资源,并且资源管理器的内存配额没有超出,则OGRE会自动帮你载入这些资源。)
        (平时我们调用“ResourceGroupManager::getSingleton().loadResourceGroup("General");”函数后,之前已被初始化的资源就进入已载入状态,它们占有内存空间。)

    本文出自 51CTO.COM技术博客

    资源组
    命名组可以作为一个整体加载与卸载。在加载,卸载,初始化时把把组中的所有资源作为一个执行单位来
    看待,而不是逐个进行处理。资源组管理纯粹是了为了管理上的方便,是否使用组的方式与性能无关。假
    如向资源组管理器中加入了资源位置而没有指定组名,那么这些资源位置被放入"General"组中。


    资源组与世界几何
    缺省情况下,ogre把加载的世界几何放入"General"组。也可以覆盖(override)这种方式,使得对世界几何的管理像其他资源的管理方式一样。统一的场景管理器可以提供关于装载世界总步骤的线索,这样就可以在关卡加载时,提供精确的以进度条显示的反馈信息。

    资源位置(location)
    资源位置是ogre去查找资源进行索引的地方。索引指的是在某个位置的所有资源通过它们的名字被映射,这样可以方便进行更快的查找资源。可以在程序的任何时候添加或删除资源位置,不必事先对所以可能用到的进行定义。资源位置在ogre中实际上是个archive,它的意思就是“文件的集合”。磁盘上的文件系统是archive的一种类型。另外一种是zip archive。可以自定义archive格式。这通过改写archive类实现来完成,必须支持对命名的leaf文件进行枚举操作,必须支持通配符,支持结点递归,给ogre提供一个流访问archive中文件的数据。ogre中的archive是只读的。ogre资源管理器利用archive枚举特性来索引archive的内容,当ogre对archive进行索引时,不会实际加载任何资源。

    资源生命周期
    资源有四种状态,各状态之间的转换关系如下图:



    Undefined:这是程序开始时,所有资源的缺省状态。除非它们被声明,ogre对程序用到的资源一无所知,手工调用代码 ResourceGroupManager::declareResource()或在脚本中被解析之后,资源的状态变为Declared
    Declared:声明就是告诉ogre想要加载某些资源。ResourceGroupManager::declareResource()总是有效的,包括在渲染系统初始之前,这与ResourceManager::create()不同,因为后者依赖于渲染系统。
    Unloaded:通过调用ResourceGroupManager::initialiseAllResourceGroup(), ResourceGroupManager::initialiseResourceGroup(),或Root::initialise()(它会初始化在此调用之前所有声明的资源),资源状态进入到Unloaded,资源会占用一点内存来保存它的定义的实例,但是资源本身还没有加载到内存。从另一角度看(从Loaded到Unloaded),引起状态变化的调用有:ResourceManager::unload(),ResourceManager::unloadAll(), ResourceManager::unloadAllUnreferencedResources(),ResourceGroupManager::unloadResourceGroup(), or Resource::unload().所有这些调用仍会保存资源实例,但真正的资源数据会从内存中卸载。
    Loaded: 这种状态下,所有数据都变得有效。与此状态有关的调用有Resource::load(), Resource::reload(),ResourceManager::load(), ResourceManager::reload(), ResourceManager::reloadAll(),ResourceManager::reloadAllUnreferencedResources(), and ResourceGroupManager::loadResourceGroup().

    逻辑资源管理
    资源以命名组的形式组织,每组可以包括任何类型的资源,每种资源都有自己的资源管理器,后者负责加载与卸载特定类型的资源。ogre对它的资源没有实现特定的内存管理方案,如果你需要对某种资源实“最近最少使用算法”方案来进行管理,那么需要自己的代码来实现。值的一提的是,现在的大多数显卡驱动,对于大多数重要的资源已经实现了这种LRU算法管理。

    资源加载
    假如没有预加载,当资源被访问时会进行加载。实际的加载,卸载是资源自己的责任。

    手动加载资源
    资源管理层不负责实际的加载与卸载。通常,不必担心资源是否存在于易失性媒介。然而,手工方式时需要考虑。手工资源加载器必须在任何时候准备好重新加载资源。假如某个资源是通过程序生成的,那么手工资源加载器必须内存中缓冲这些资源,或者是当资源管理加载时重新创建它。ogre认为手工加载与自动加载没有区别。

    后台资源管理
    缺省,ogre不是线程安全的。假如在OgreConfig.h中 #define OGRE_THREAD_SUPPORT 1 ,那么资源管理
    代码的线程同步功能变得有效,我们就可以在包含Root实例的线程之外,开启新的线程对资源管理类与方法进行操作,从而实现灵活的资源加载方案。

    非后台资源管理
    Ogre中大量使用了Observer模式,资源管理系统也不例外。ResourceGroupListene 回调接口包含了几个方法
    允许对资源加载过程进行细粒度的监听。

    资源卸载
    资源被加载后总存在于内存中,直到被应用程序强行卸载(通过资源组管理器或是被资源直接释放)。资源管理组管理会把组中所有的资源都卸载掉。在资源被引用时不能强行卸载。

    Resource Locations

    // 配置文件方式
    ConfigFile cf;
    cf.load("resources.cfg");
    // Go through all sections & settings in the file
    ConfigFile::SectionIterator seci = cf.getSectionIterator();
    String secName, typeName, archName;
    while (seci.hasMoreElements())
    {
    secName = seci.peekNextKey();
    ConfigFile::SettingsMultiMap *settings = seci.getNext();
    ConfigFile::SettingsMultiMap::iterator i;
    for (i = settings->begin(); i != settings->end(); ++i)
    {
    typeName = i->first;
    archName = i->second;
    ResourceGroupManager::getSingleton().addResourceLocation(
    archName, typeName, secName);
    }
    }


    //硬编码方式
    ResourceGroupManager *rgm = ResourceGroupManager::getSingletonPtr();
    rgm->addResourceLocation("../../media/packs/OgreCore.zip", "Zip", "Bootstrap");
    rgm->addResourceLocation("../../media", "FileSystem", "General");
    rgm->addResourceLocation("../../media/fonts", "FileSystem", "General");

    初始化
    在初始化之前,必须创建至少一个渲染窗口。因为在分析脚本时可能会创建GPU资源,而后者需要渲染上下文。


    // initialize all of the previously defined resource groups
    ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
    // or, alternately, initialize the defined resource groups one at a time
    ResourceGroupManager::getSingleton().initialiseResourceGroup("General");
    ResourceGroupManager::getSingleton().initialiseResourceGroup("Bootstrap");


    卸载
    可以在任何时候卸载资源(以组或单个的方式),正在使用的资源不会被卸载。

    以组的方式卸载
    ResourceGroupManager::getSingleton().unloadResourceGroup("Bootstrap", true);
    ResourceGroupManager::getSingleton().
    unloadUnreferencedResourcesInGroup("Bootstrap", true);
    true表示只卸载资源数据,不删除资源实例,它可以被reloaded。有些资源在创建时被标为
    "nonreloadable",这种类型的资源不能使用上述方法卸载。

    清理或销毁资源组
    清理仅是卸载资源与分离资源索引,销毁不仅做清理的工作,还包括从资源组中把自己移除。
    ResourceGroupManager::geSingleton().clearResourceGroup("Bootstrap");
    ResourceGroupManager::geSingleton().destroyResourceGroup("Bootstrap");

    以个体方式卸载
    // assume that pEntity is a valid pointer to an instance of Entity
    MeshPtr meshPtr = pEntity->getMesh();
    meshPtr->unload();

    加载/重载资源组
    ResourceGroupManager::getSingleton().loadResourceGroup("Bootstrap", false, true)
    二个布尔变量不同资源类型资源加载开关,一针对"Normal"资源,二针对"World geometry"

    资源组加载通知
    class LoadingProgressListener : public ResourceGroupListener
    {
       public: 
    // fired when a group begins parsing scripts
                    void resourceGroupScriptingStarted(const String& groupName,
                                                                            size_t scriptCount) {}
    // fired when a script is about to be parsed
                   void scriptParseStarted(const String& scriptName) {}
    // fired when the script has been parsed
                   void scriptParseEnded() {}
    // fired when all scripts in the group have been parsed
                  void resourceGroupScriptingEnded(const String& groupName) {}
    //还有一些接口
    }


    //实现之后,进行注册
    LoadingProgressListener listener(m_progressMeter);
    ResourceGroupManager::getSingleton().addResourceGroupListener(&listener);

  • 相关阅读:
    【总结】Centos中,Kerberos安装
    Go语言mgo
    Go语言mgo
    理解 Serenity,Part-1:深度抽象
    ZCash零知识证明
    零知识证明(Zero-Knowledge Proof)原理详解:非交互式证明实现自动验证防止作假
    tf.shape(x)、x.shape、x.get_shape()函数解析(最清晰的解释)
    Java生成(m.n)之间的随机数
    tf.cond()函数解析(最清晰的解释)
    OpenStack Blazar 架构解析与功能实践
  • 原文地址:https://www.cnblogs.com/pulas/p/2777705.html
Copyright © 2011-2022 走看看