The Beginner Guide to Resource Groups
If you have read The Beginner Guide to Getting CEGUI Rendering, you probably have your application set-up to perform the basic CEGUI initialisation steps and to call the System::renderGUI method, which is all very nice; but lets face it, you still can't get anything to draw!
The next stage in this quest for the 'holy grail' (that is, to actually get CEGUI to work) is to setup resource provider groups that will later enable us to load some files so that CEGUI has some source materials to use when rendering.
Contents
What is a ResourceProvider?
CEGUI makes use of a helper object which we call the ResourceProvider. This object provides an interface between the core CEGUI library and any external file loading system.
For example, the Ogre and Irrlicht engines have their own resource manager / file loading sub-systems, by implementing and supplying a specialised ResourceProvider object, the renderer modules for these engines allow seamless integration with these systems so that CEGUI data files are loaded via these systems. The lower level Direct3D and OpenGL libraries do not have their own resource systems as such, so for these you can use the CEGUI default resource provider.
DefaultResourceProvider Explained
CEGUI's default resource provider, CEGUI::DefaultResourceProvider, supplies some basic functionality for those who do not yet have, or do not need, a more sophisticated alternative. As well as supplying the functions required by CEGUI for actually loading files and data, DefaultResourceProvider also has some rudimentary support for 'resource groups'. Here, a resource group is basically a label given to a directory or path on the system. This allows us to have logical grouping of files within directories and then to be able to refer to those location via a simple label rather than hard coded paths. In the simplest case this means that you just need to update the resource group location instead of updating path information throughout your code and in the XML files when you change the location of the data files.
Specifying Resource Groups and Directories
The DefaultResourceProvider allows you to define any number of named resource groups and to specify a directory to be used for each group. What this means is that you can create a resource group, say “imagesets” and assign a directory to that, for example “./mygame/datafiles/gui/imagesets/”. Then when loading an Imageset through the ImagesetManager, you could specify the resource group to be used as “imagesets” and the system will look in the predefined location. At present each resource group may only have a single directory assigned to it.
A small code example is in order to clarify what has been said. Where as previously, without the use of resource groups, you might have done this:
<cpp/>
Imageset* wlis = ImagesetManager::getSingleton().createImageset(
"./mygame/datafiles/gui/imagesets/WindowsLook.imageset");
Using resource groups, at initialisation time, you create the resource groups in the default resource provider, like this:
<cpp/>
DefaultResourceProvider* rp = static_cast<DefaultResourceProvider*>(
CEGUI::System::getSingleton().getResourceProvider());
rp->setResourceGroupDirectory("imagesets", "./mygame/datafiles/gui/imagesets/");
Then later on in the code, when you need to load the imageset, you can reference the resource group to be used, like this:
<cpp/>
Imageset* wlis = ImagesetManager::getSingleton().createImageset(
"WindowsLook.imageset", "imagesets");
Note how you do not need to specify any path information; the path information is obtained from the resource group specified, in the example this is "imagesets". We will later show you how you set default resource groups for each of the resource types – then you do not have to specify the group when you load a resource (unless you're loading it from a group that is not the default, of course).
Another important thing to consider is that using this approach, the data files should not contain relative path information – they should, in general, just have the actual file name.
Default Resource Groups
Each of the system classes that represents a loadable resource has static members to set and get a default resource group. This resource group will be used when loading the specific data files needed by a given class – in the case of the Imageset class, the default resource group should reference a directory holding the imageset xml and texture image files.
For each of the resource consuming classes, the static members are named the same (special exception is xerces – see below):
<cpp/>
const String& getDefaultResourceGroup();
void setDefaultResourceGroup(const String& groupname);
The following is a list of the core resource loading classes and the resources that they load:
CEGUI::Imageset - Imageset xml and texture image files. CEGUI::Font - Font xml and ttf font files. CEGUI::Scheme - Scheme xml files. CEGUI::WindowManager - Window layout xml files. CEGUI::WidgetLookManager - LookNFeel xml files CEGUI::ScriptModule - Script files in whichever scripted langauge.
There is one special exception, as mentioned above – that is the Xerces-C based XML parser. For this there is a special resource group setting to specify where the schema files can be found (these are the .xsd files used for xml validation). For this special case, the static members are:
<cpp/>
const String& XercesParser::getSchemaDefaultResourceGroup(); void XercesParser::setSchemaDefaultResourceGroup(const String& groupname);
One final thing to consider, is that the resource provider class also has a default group. This should be considered a 'global' default – it is used whenever a specific resource loading class has no default of it's own specified. This could be useful if you have all your data in a single directory.
DefaultResourceProvider Setup: A Complete Example
To close, we will show how the CEGUI samples framework does the initialisation of resource groups and their target directories, and how we assign the default groups to be used for all of the resource types.
After initialising the core CEGUI::System object as usual, we then specify a set of resource groups and their target directories:
<cpp/>
// initialise the required dirs for the DefaultResourceProvider
CEGUI::DefaultResourceProvider* rp = static_cast<CEGUI::DefaultResourceProvider*>
(CEGUI::System::getSingleton().getResourceProvider());
rp->setResourceGroupDirectory("schemes", "../datafiles/schemes/"); rp->setResourceGroupDirectory("imagesets", "../datafiles/imagesets/"); rp->setResourceGroupDirectory("fonts", "../datafiles/fonts/"); rp->setResourceGroupDirectory("layouts", "../datafiles/layouts/"); rp->setResourceGroupDirectory("looknfeels", "../datafiles/looknfeel/"); rp->setResourceGroupDirectory("lua_scripts", "../datafiles/lua_scripts/");
// This is only needed if you are using Xerces and need to
// specify the schemas location
rp->setResourceGroupDirectory("schemas", "../../XMLRefSchema/");
Now that is done, we have a nice set of resource groups defined with their target directories set. Finally, to get the system to use these new directories, we set the default resource groups to be used:
<cpp/>
// set the default resource groups to be used
CEGUI::Imageset::setDefaultResourceGroup("imagesets");
CEGUI::Font::setDefaultResourceGroup("fonts");
CEGUI::Scheme::setDefaultResourceGroup("schemes");
CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
CEGUI::WindowManager::setDefaultResourceGroup("layouts");
CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
// Again, you only need to this one if you are using xerces and have // defined a group for schemas. CEGUI::XercesParser::setSchemaDefaultResourceGroup("schemas");
Conclusion
Here you have had a brief introduction to the DefaultResourceProvider class, you have seen how to create resource groups and assign directory locations to them, and you have also seen how to specify default resource groups for each resource type CEGUI uses.