OGRE高级教程1翻译版

 

高级教程1

高级教程1:资源和资源管理器

本文的第一部分将详细介绍资源加载,卸载,加载和销毁的细节过程。在下一部分,我们将创建一个新的资源类型,和对应的管理器。

请使用本论坛主题讨论问题,建议等

Contents目录

*                               1 The Lifecycle of a Resource 1资源生命周期

*                                       1.1 Terminology 1.1 术语

*                                       1.2 Resource Creation, from the very beginning 1.2从一开始起资源的创造,

*                                       1.3 Resource Unloading and Destruction 1.3卸载和销毁资源

*                                       1.4 Reloading Resources 1.4 重新加载资源

*                               2 Creating a new Resource type, and the accompanying ResourceManager 2 创建一个新的资源类型,和与之对应的管理器

*                                       2.1 ScriptLoader 2.1 脚本加载器

*                                       2.2 ManualResourceLoader 2.2 手动资源加载器

*                                       2.3 Usage 2.3 使用

The Lifecycle of a Resource资源的生命周期

OGREThe OGRE API documentation explains the basic lifecycle of a resource, but is slightly washy with some of the concepts.OGREOGREAPI文档的说明了资源的基本生命周期,但略有一些概念混淆。 Hopefully, things will be made clearer here.我们希望,会更清晰一点。

Terminology 术语

The following terms will be used to distinguish the various stages of loading that a resource may be in:以下条款将被用来区分可在不同阶段加载一个资源:

Unknown : OGRE is not aware of the resource. 未知(Unknown OGRE不能识别资源的存在。 Its filename is stored in a ResourceGroup, but OGRE has no idea what to do with it.它的文件名存储在一个资源组(ResourceGroup),但OGRE不知道如何处理它。
Declared : The resource has been flagged for creation, either directly or as a side-effect of some other action. 声明(Declared :资源被标记已创建,直接或间接的对其他一些行为产生影响。  OGREOgre knows what type of resource it is, and what to do with it when the time comes to create it.OGREOGREOGREOg 知道它的资源的类型,以及如何与它做在时机成熟时创建它。
Created : OGRE has created an empty instance of the resource, and added it to the relevant ResourceManager. 创建(Created OGRE创造了空的资源实例,并添加到相关的资源管理器(ResourceManager)中。
Loaded : The created instance has been fully loaded, and the resource's full data now resides in memory. 加载 Loaded):创建的实例已被全部加载,资源的所有数据现在驻留在内存中。 This is typically the stage at which the resource's file is actually accessed.这实际上通常是在访问该资源的文件阶段出现。 You do not want to access the file in the Creation stage.你不想在创建阶段访问文件。


Resouces do not take much space until they are loaded, therefore there is no harm in adding all of your resources to the resource manager first and then load/unload them as needed in your application. 资源直到他们被加载才占用空间,,所以不存在增加全部资源造成资源管理器损坏的问题,然后在你的应用程序所需的时候加载/卸载它们。

Resource Creation, from the very beginning从一开始就创造资源

1.     OGRE 自带的资源管理器在根节点处创建。

2.    The first thing that needs to be done is to specify resource locations.第一件事需要做的是指定资源的位置。  This is done by calling ResourceGroupManager::addResourceLocation.这是通过调用ResourceGroupManager::addResourceLocation来实现的。这个函数处理以下几件事情:

1.  Creates the specified ResourceGroup if this hasn't been done already.如果没有这样做了,创建指定的资源组。

2.  Creates a new Archive instance of the type specified创建指定类型新的文档实例

3.  Creates a new ResourceLocation, adds the Archive to it, and then adds the ResourceLocation to the ResourceGroup.创建一个新资源位置,对它增加文档,然后添加资源位置(ResourceLocation)到资源组(ResourceGroup)。

4.  The final step is to get a list of all the files in the Archive, and add them to a list in the ResourceGroup.最后一步是获取所有的文档文件列表,并将其添加在资源组(ResourceGroup)名单。 After this step has completed, resources are in the Unknown stage.经过这一步完成后,资源的处于未知(Unknown阶段。

3.    The next step is to manually declare resources.下一步是手动声明资源。 At this point no resources are declared, though many of them will be declared when the ResourceManager starts parsing scripts.在这个时候没有资源被声明,虽然当资源管理器(ResourceManager)解析脚本的时候,他们不少人将被宣布启动时的许多资源将会被声明。如果你想手动声明资源,调用Reso urceGroupManager。::declareResource函数。 At this point, any resources that have been manually declared are in the Declared stage.在这一点上,任何已被手动声明资源处在声明阶段。 The rest are still Unknown .其余的都是未知阶段

4.    Next the ResourceGroups are initialized.接下来,ResourceGroups初始化。 This is done with ResourceGroupManager::initialiseResourceGroup or ResourceGroupManager::initialiseAllResourceGroups, the latter just calling the former for all ResourceGroups.这是通过ResourceGroupManager::initialiseResourceGroupResourceGroupManager::initialiseAllResourceGroups实现的,后者为所有的ResourceGroups调用前一个函数。 This does the following:它它它  它这样子实现

§                    Parses any scripts in the ResourceGroup.解析资源组(resourceGroup 中的所用脚本。 Scripts are defined by ResourceManagers which inherit from ScriptLoader.脚本的定义是通过从脚本加载器(ScriptLoader)继承的资源管理器实现的。 This may cause some resources to be Declared .这可能会导致一些资源需要被声明

§                    Creates any Declared resources.建立所有的资源声明。

§                    The relevant ResourceManager creates a new instance of the resource, and adds it to itself.有关的资源管理器(ResourceManager)创建一个新的资源实例,并将其添加到自己所在的组。 All resources are stored in ResourceManagers.所有资源都存储在资源管理器(ResourceManagers)中。

§                    The resource is also inserted into an "ordered loading list".资源也是插入到命令装货清单中。 This allows resources to be loaded in a specific order, if you want to load an entire ResourceGroup at once.这使资源在一个特定的顺序加载,如果你想一次加载整个资源组(ResourceGroup)。 The load order for a resource is specified by its ResourceManager.资源的加载顺序由(资源管理器)ResourceManager指定。

§                    At this point, any Declared resources are now in the Created stage.在这一点上,任何声明的资源目前正处于创建阶段。

5.    Finally, we're done with initialization.最后,我们完成了初始化。 No resources are loaded yet, but that's fine, because we're not using any.没有资源被加载,但很好,因为我们没有使用资源。 The final step - the transition from Created to Loaded - can come about in the following ways:最后一步-从创建到加载过渡-可以来了解以下方式:

§                    The resource was used.使用使用使用资源。For example, an Entity was created which needed a specific mesh.例如,需要特定的网格的实体被创建。 Obviously, once a resource has been loaded in this way, it will not be loaded again if another Entity needs it.显然,一旦资源以这种方式加载的,如果另一个实体需要的时候,它不会再加载了。 If the resource is currently in the Unknown state, it will be created and fully loaded.如果资源目前正处于未知状态,它将会创建和全部加载。

§                    ResourceGroupManager::loadResourceGroup is called - any Created resources are loaded. ResourceGroupManager:: loadResourceGroup -被称为任何创建资源被加载。

§                    The relevant ResourceManager's load method is called.有关的资源管理器(ResourceManager)的加载方法被调用。 This can be used to load resources which have not yet been Created, because it will automatically Create them for you first, if necessary.这可以用来装载尚未创建的资源,因为如有必要,它会自动为您创建他们的第一次加载。

§                    The resource is loaded directly, by obtaining a pointer to it, and calling its load method.通过获取指向它的指针,资源是被直接加载,并调用它的加载方法。当然You can only do this if the resource is in the Created stage, of course.如果资源是处于创建阶段,你只能这样做,。

§                    At this point, Loaded resources are ready to use straight away.在这一点上, 加载资源准备马上使用。

Note : If you have created any custom ResourceManagers, you must initialize them before manually declaring resources or some of them may not be found. 注意 :如果您已经创建任何自定义资源管理器(ResourceManagers),您必须手动声明资源或其中一些可能无法找到的资源在初始化他们之前。

In your application, this generally boils down to the following sequence of events:在您的应用程序,这通常归结为以下事件序列:

1.    Create the Root object.创建根对象。

2.    反复调用Call ResourceGroupManager::addResourceLocation repeatedly until you have added all resource locations.调用调用ResourceGroupManager::addResourceLocation,直到添加完所有资源的位置。

3.    Create any custom ResourceManager objects you have made and register them using ResourceGroupManager::_registerResourceManager.创建任何自定义的您所使用的资源管理器(ResourceManager)对象的并使用ResourceGroupManager::_registerResourceManager注册他们。 You should also register any ScriptLoader objects with the ResourceGroupManager::_registerScriptLoader function.您还应该通过调用ResourceGroupManager::_registerScriptLoader函数注册所有的脚本加载器(ScriptLoader)对象。

4.    Manually declare any resources you require with the ResourceGroupManager::declareResource function.手动声明您的任何资源与ResourceGroupManager::declareResource函数所需要的任何资源。

5.    Call the appropriate initialization function for your resource groups.为问哦为资源组调用适当的初始化函数。 Either use ResourceGroupManager::initialiseResourceGroup for a single group or call ResourceGroupManager::initialiseAllResourceGroups to initialize everything at once.要么使用ResourceGroupManager::initialiseResourceGroup去初始化一个组,或调用ResourceGroupManager::initialiseAllResourceGroups去立即初始化所用的东西。

Resource Unloading and Destruction 资源卸载和销毁

资源管理器(ResourceManager)::从加载创建资源卸载还原资源。

To completely remove a resource, call ResourceManager::remove.要完全删除资源,调用的ResourceManager::remove This returns the resource all the way back to the Unknown stage, from whichever stage it was in previously.这将资源从以前的那个阶段一路回到未知阶段。 You can get a pointer to the resource with ResourceManager::getByName and unload or remove it manually, if you wish.你可以通过调用ResourceManager::getByName获取一个指向资源的指针和如果你想的话,卸载或者手动删除它。

*                   Any existing resources are removed when a ResourceManager is destructed.当资源管理器(ResourceManager)被销毁的时候任何现有的资源都被被删除。

Reloading Resources 重新加载资源

Reloading resources is a very useful feature for editors.重载资源是非常有用的编辑功能。 Essentially, the resource is unloaded, and then loaded.从本质上讲,资源先被卸载,然后加载。 It moves from Loaded, to Created and then back to Loaded again.它从加载到创建,然后再回到加载阶段。 Resources must be in the Loaded stage to be reloaded.资源必须在加载阶段时重新加载。

*                   ResourceManager::reloadAll reloads all resources of one type.ResourceManager:: reloadAll 重新加载所有的同一类型的资源。

*                   Resources can be individually reloaded with Resource::reload资源可以单独重新加载通过使用 Resource::reload

Creating a new Resource type, and the accompanying ResourceManager 创建新的资源类型,和所附的资源管理器

Now that we know how OGRE's resource system works, creating a new resource type is actually pretty easy.现在我们知道如何OGRE的资源系统如何工作,创造新的资源类型,其实非常简单。 Your application will almost certainly use extra resources, be they sound files, XML or just plain text.您的应用程序几乎肯定会使用额外的资源作为声音文件,XML或只是纯文本。 In this example, we'll create a simple text file loader.在这个例子中,我们将创建一个简单的文本文件加载器。 The code is neatly compartmentalized, and easy to extend to any file type - the only thing that will need to change is the Resource::load method, and the TextFile resource's public interface to access the data we have loaded.该代码是整齐分割,易于扩展到任何类型的文件-唯一需要改变是Resource::Load方法,以及我们加载的数据去访问文件资源的公共接口。

There are two caveats to this: script resources, and manual resource loaders.有两个限制性条件是:脚本资源和手动资源装载器。 This example will use neither, but they will be explained.这个例子都没有使用两者,但它们将得到解释。

The first file to create is TextFile.h.第一个将被创建的是TextFile.h文件。 This declares our resource, TextFile, and creates a shared pointer implementation for it.这将声明我们的资源,文本文件,以及创建这个共享指针的执行情况。下面是它的源代码This is what it looks like:  

#ifndef __TEXTFILE_H__
#define __TEXTFILE_H__
 
#include <OgreResourceManager.h>
 
class TextFile : public Ogre::Resource
{
    Ogre::String mString;
 
protected:
    //一定要执行这些来自Ogre::Resource的接口
    void loadImpl();
    void unloadImpl();
    size_t calculateSize() const;
 
public:
 
    TextFile(Ogre::ResourceManager *creator, const Ogre::String &name, 
        Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual = false, Ogre::ManualResourceLoader *loader = 0);
 
    virtual ~TextFile();
 
    void setString(const Ogre::String &str);
    const Ogre::String &getString() const;
};
 
class TextFilePtr : public Ogre::SharedPtr<TextFile> 
{
public:
    TextFilePtr() : Ogre::SharedPtr<TextFile>() {}
    explicit TextFilePtr(TextFile *rep) : Ogre::SharedPtr<TextFile>(rep) {}
    TextFilePtr(const TextFilePtr &r) : Ogre::SharedPtr<TextFile>(r) {} 
    TextFilePtr(const Ogre::ResourcePtr &r) : Ogre::SharedPtr<TextFile>()
    {
        // lock & copy other mutex pointer
        OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
            OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
            pRep = static_cast<TextFile*>(r.getPointer());
        pUseCount = r.useCountPointer();
        if (pUseCount)
        {
            ++(*pUseCount);
        }
    }
 
    /// Operator used to convert a ResourcePtr to a TextFilePtr
    TextFilePtr& operator=(const Ogre::ResourcePtr& r)
    {
        if (pRep == static_cast<TextFile*>(r.getPointer()))
            return *this;
        release();
        // lock & copy other mutex pointer
        OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
            OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
            pRep = static_cast<TextFile*>(r.getPointer());
        pUseCount = r.useCountPointer();
        if (pUseCount)
        {
            ++(*pUseCount);
        }
        return *this;
    }
};
 
#endif

Here is the accompanying .cpp file.这里是对应的。cpp文件。 We are using a simple string to store our data, and as such it needs no special initialisation.我们正在使用一个简单的字符串来存储的数据,因此,它不需要特殊的初始化。 If you are using more complex objects, they must be initialised appropriately.如果您使用更复杂的对象,必须适当地初始化。

 #include "TextFile.h"#include "TextFile.h"
#include "TextFileSerializer.h"
 
TextFile::TextFile(Ogre::ResourceManager* creator, const Ogre::String &name, 
                    Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual, 
                    Ogre::ManualResourceLoader *loader) :
Ogre::Resource(creator, name, handle, group, isManual, loader)
{
    /* If you were storing a pointer to an object, then you would set that pointer to NULL here.
    */
 
    /* For consistency with StringInterface, but we don't add any parameters here
    That's because the Resource implementation of StringInterface is to
    list all the options that need to be set before loading, of which 
    we have none as such. Full details can be set through scripts.
    */ 
    createParamDictionary("TextFile");
}
 
TextFile::~TextFile()
{
    unload();
}
 
// farm out to TextFileSerializer
void TextFile::loadImpl()
{
    TextFileSerializer serializer;
    Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(mName, mGroup, true, this);
    serializer.importTextFile(stream, this);
}
 
void TextFile::unloadImpl()
{
    /* If you were storing a pointer to an object, then you would check the pointer here,
    and if it is not NULL, you would destruct the object and set its pointer to NULL again.
    */
 
    mString.clear();
}
 
size_t TextFile::calculateSize() const
{
    return mString.length();
}
 
void TextFile::setString(const Ogre::String &str)
{
    mString = str;
}
 
const Ogre::String &TextFile::getString() const
{
    return mString;
}

You will have noticed the reference to "TextFileSerializer" in the includes.你会发现提及的“TextFileSerializer”包括在内。 This is a helper class which does the actual loading.这是一个事实上未被加载的帮助类。 It is not vital, especially for a resource this simple, but it allows us to serialize an object without having to wrap a Resource around it, should we want to.尤其是对资源这个简单,它并非是必不可少的,但它允许我们使对象连续,而不必在对象周围环绕资源,这是我们应该想做的事情。 The Serializer base class contains lots of useful utility functions.该串行器基类包含了许多有用的实用功能。 We won't use them, but will subclass from it anyway.我们不会使用它们,但无论如何,它的子类将会继承它。

TextFileSerializer.h: TextFileSerializer.h

#ifndef __TEXTSERIALIZER_H__
#define __TEXTSERIALIZER_H__
 
#include <OgreSerializer.h>
 
class TextFile; // forward declaration
 
class TextFileSerializer : public Ogre::Serializer
{
public:
    TextFileSerializer();
    virtual ~TextFileSerializer();
 
    void exportTextFile(const TextFile *pText, const Ogre::String &fileName);
    void importTextFile(Ogre::DataStreamPtr &stream, TextFile *pDest);
};
 
#endif

TextFileSerializer.cpp: TextFileSerializer.cpp

 #include "TextFileSerializer.h"#include "TextFileSerializer.h"
#include "TextFile.h"
 
TextFileSerializer::TextFileSerializer()
{
}
 
TextFileSerializer::~TextFileSerializer()
{
}
 
void TextFileSerializer::exportTextFile(const TextFile *pText, const Ogre::String &fileName)
{
    std::ofstream outFile;
    outFile.open(fileName.c_str(), std::ios::out);
    outFile << pText->getString();
    outFile.close();
}
 
void TextFileSerializer::importTextFile(Ogre::DataStreamPtr &stream, TextFile *pDest)
{
    pDest->setString(stream->getAsString());
}

The last class we need to write is of course the TextFileManager.最后一堂课,我们需要编写当然是TextFileManager

TextFileManager.h: TextFileManager.h

#ifndef __TEXTFILEMANAGER_H__
#define __TEXTFILEMANAGER_H__
 
#include <OgreResourceManager.h>
#include "TextFile.h"
 
class TextFileManager : public Ogre::ResourceManager, public Ogre::Singleton<TextFileManager>
{
protected:
 
    // must implement this from ResourceManager's interface
    Ogre::Resource *createImpl(const Ogre::String &name, Ogre::ResourceHandle handle, 
        const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader, 
        const Ogre::NameValuePairList *createParams);
 
public:
 
    TextFileManager();
    virtual ~TextFileManager();
 
    virtual TextFilePtr load(const Ogre::String &name, const Ogre::String &group);
 
    static TextFileManager &getSingleton();
    static TextFileManager *getSingletonPtr();
};
 
#endif

And finally, TextFileManager.cpp最后是TextFileManager.cpp

#include "TextFileManager.h"
 
template<> TextFileManager *Ogre::Singleton<TextFileManager>::ms_Singleton = 0;
 
TextFileManager *TextFileManager::getSingletonPtr()
{
    return ms_Singleton;
}
 
TextFileManager &TextFileManager::getSingleton()
{  
    assert(ms_Singleton);  
    return(*ms_Singleton);
}
 
TextFileManager::TextFileManager()
{
    mResourceType = "TextFile";
 
    // low, because it will likely reference other resources
    mLoadOrder = 30.0f;
 
    // this is how we register the ResourceManager with OGRE
    Ogre::ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this);
}
 
TextFileManager::~TextFileManager()
{
    // and this is how we unregister it
    Ogre::ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType);
}
 
TextFilePtr TextFileManager::load(const Ogre::String &name, const Ogre::String &group)
{
    TextFilePtr textf = getByName(name);
 
    if (textf.isNull())
        textf = create(name, group);
 
    textf->load();
    return textf;
}
 
Ogre::Resource *TextFileManager::createImpl(const Ogre::String &name, Ogre::ResourceHandle handle, 
                                            const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader, 
                                            const Ogre::NameValuePairList *createParams)
{
    return new TextFile(this, name, handle, group, isManual, loader);
}

脚本加载器(ScriptLoader ScriptLoader

Some resources, such as materials, are loaded from scripts, and in these cases, the ResourceManager will derive from ScriptLoader.一些资源,比如说材料是从脚本加载的,在这些情况下,则ResourceManager将来自ScriptLoader It will then set up its 'script patterns' - the filetypes that it considers as scripts (*.material, *.compositor, etc) - in the constructor.然后它将设立了'脚本格式' -该文件类型的脚本,它认为(*.material, *.compositor, etc)脚本在构造器中式文件类型 在这一点它将调用It will also call ResourceGroupManager::_registerScriptLoader at this point to register itself as a script loading ResourceManager.这时候 这时候ResourceGroupManager:: _registerScriptLoader注册为加载ResourceManager脚本本身。 Later, when ResourceGroupManager::initialiseResourceGroup is called, any registered script files will be parsed.后来,当ResourceGroupManager::initialiseResourceGroup被调用时,任何注册的脚本文件将被解析。

If you wish to write a script-loading ResourceManager, you will need to derive from ScriptLoader, and implement the parseScript method.如果您想编写一个加载脚本的ResourceManager,您将需要从ScriptLoader写起,执行parseScript方法。ResourceGroupManager::initialiseResourceGroup方法时It is parseScript that gets called on the resources during ResourceGroupManager::initialiseResourceGroup, and this is where you should declare any resources that you want created.parseScript将会被调用,这是你应该声明任何您想要创建的资源。

ManualResourceLoader ManualResourceLoader

When a resource is declared with ResourceGroupManager::declareResource, it may be given an optional ManualResourceLoader.当用ResourceGroupManager::declareResource声明资源的时候,它可能获得一个可选ManualResourceLoader ManualResourceLoaders can be used for resources which are not loaded from file - they may be created programmatically. ManualResourceLoaders可用于不是从文件中加载资源-他们可能以编程方式创建的资源。 Here is a simple example, using TextFile:下面是一个简单的例子,使用TextFile:

 // Do not add this to the project / /不要把这部分内容添加到项目里边

class ManualTextFileLoader : public Ogre::ManualResourceLoader
{
public:
 
   ManualTextFileLoader() {}
   virtual ~ManualTextFileLoader() {}
 
   void loadResource(Ogre::Resource *resource)
   {
       TextFile *tf = static_cast<TextFile *>(resource);
       tf->setString("manually loaded");
   }
};

The TextFile is then declared as follows:TextFile文件被声明如下:

 // Do not add this to the project / /不要把这部分内容添加到项目里边

ManualTextFileLoader *mtfl = new ManualTextFileLoader;

Ogre::ResourceGroupManager::getSingleton ().declareResource("hello.txt", "TextFile", "General", mtfl);Usage

用法

To use our new resource manager, we create an instance before Root::initialise or any ResourceGroups have been initialized .若要使用新的资源管理器,在Root::initialise或任何ResourceGroups已初始化之前,我们创建了一个实例。

 TextFileManager *tfm = new TextFileManager(); TextFileManager *tfm = new TextFileManager();

And we destruct it when we shutdown - before we destroy the Ogre::Root object, of course.我们撤销它,当我们关闭当然也就是在我们销毁Ogre::Root对象之前。OGRE没有破坏它自身,这是你的职责:

delete Ogre::ResourceGroupManager::getSingleton()._getResourceManager("TextFile");

The last thing we will do is look at an example of what we have created in action.我们最需要做的是看一个我们已经创建的例子 。新建一个名为“hello.txt”的文件,并将其放置在一个media目录下OGRE可以找到它。 Since there really isn't a location for custom scripts, I suggest putting the file in "media/materials/scripts".由于确实吗没有存放一个自定义脚本的位置,我建议把该文件放在"media/materials/scripts"目录下 Add the following to that text file:以下内容添加到该文本文件:

 Hello world! 

 

Now create a file called main.cpp and add the following code to it.现在创建一个名为main.cpp的文件,并添加下面的代码给它。 Be sure to read through the createScene function to see some of the things we can do with this:一定要通读createScene的功能,我们可以做这样一些:

#include <ExampleApplication.h>
 
#include "TextFileManager.h"
#include "TextFileSerializer.h"
 
class TutorialApplication : public ExampleApplication
{
private:
    TextFileManager *mTFM;
public:
    TutorialApplication()
        : mTFM(0)
    {
    }
 
    ~TutorialApplication()
    {
        delete mTFM;
    }
 
    void setupResources()
    {
        mTFM = new TextFileManager();
 
        // hello.txt will be created when initialiseResourceGroup is called
        ResourceGroupManager::getSingleton().declareResource("hello.txt", "TextFile");
        ExampleApplication::setupResources();
    }
 
    void createScene(void)
    {
        // Load the file, get the data
        TextFilePtr textfile = mTFM->load("hello.txt", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
        String str = textfile->getString();
 
        // Reload the file
        textfile->reload();
 
        // export the file
        TextFileSerializer serializer;
        serializer.exportTextFile(static_cast<TextFile *>(textfile.getPointer()), "hello.out.txt");
 
        // unload/remove the file
        mTFM->unload("hello.txt");
        mTFM->remove("hello.txt");
    }
};
 
#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
 
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    TutorialApplication app;
 
    try {
        app.go();
    } catch(Exception& e) {
#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBoxA(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occurred: %s/n",
            e.getFullDescription().c_str());
#endif
    }
 
    return 0;
}

If you step through this function with a debugger, you will see that see that calling getString will indeed return the contents of hello.txt.如果您通过此功能与调试步骤,你会看到调用的getString,确实将返回hello.txt的内容。 While this may not be the most useful thing in its current state, you can easily expand this to create your own resources and resource loaders.虽然这未必是在其当前状态最有用的东西,你可以很容易地扩展这个创建您自己的资源和资源装载机。

 

OGRE---旺

译于2009--11--29晨

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值