Add resources (again)

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
spookyboo
Silver Sponsor
Silver Sponsor
Posts: 1141
Joined: Tue Jul 06, 2004 5:57 am
x 151
Contact:

Add resources (again)

Post by spookyboo »

I'm trying to add a new resource location using the 1.0.0 version, but this results in an assert in the TerrainSceneManager (cannot setup the material). It works when I add the paths in the resources.cfg. It worked in the 15.1 version though. What I'm trying to do is:

Code: Select all

Root::getSingleton().addResourceLocation (relativePath, "FileSystem");
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
I guess its me doing something wrong, but I'm lost at the moment. I have no clue how to add the new location and force parsing the material scripts in that location (parseAllSources in the MaterialManager is gone; I do see a parseScript but it uses a data stream pointer. )
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 67
Contact:

Post by sinbad »

If you want to parse scripts in a particular location, you should add those locations to a group of their own (ResourceGroupManager::createResourceGroup) and call initialiseResourceGroup on that one group. initialiseAllResourceGroups will also work if that's the only group(s) you added since the last time you called initialiseAllResourceGroup, since it won't initialise resource groups that have already been initialised.
User avatar
spookyboo
Silver Sponsor
Silver Sponsor
Posts: 1141
Joined: Tue Jul 06, 2004 5:57 am
x 151
Contact:

Post by spookyboo »

I have tried that also. I'm using a custom material in combination with the TerrainSceneManager. It is all OK if I use the DEFAULT_RESOURCE_GROUP_NAME for the material script and textures, but not if I use a custom group.
If i declare my paths directly in the General section of the resources.cfg it also works, but if a declare a custom section in the .cfg and put the paths in the custom section, it doesn´t work. This is the call stack

Code: Select all

_assert(void * 0x01184448 `string', void * 0x011843e4 `string', unsigned int 93) line 256
Ogre::SharedPtr<Ogre::Material>::operator->() line 93 + 58 bytes
Ogre::TerrainSceneManager::setupTerrainMaterial() line 365 + 10 bytes
Ogre::TerrainSceneManager::setWorldGeometry(const _STL::basic_string<char,_STL::char_traits<char>,_STL::allocator<char> > & {...}) line 457
World::Terrain::load(_STL::basic_string<char,_STL::char_traits<char>,_STL::allocator<char> > {...}, TiXmlElement * 0x00000000) line 1310 + 26 bytes
World::Terrain::init(Ogre::Root * 0x016e8108, Ogre::Camera * 0x017150f0, Ogre::SceneManager * 0x01704fd8, Ogre::RenderWindow * 0x0170ba98, _STL::basic_string<char,_STL::char_traits<char>,_STL::allocator<char> > {...}) line 936
World::GuiApplication::createScene() line 871
ExampleApplication::setup() line 95 + 13 bytes
ExampleApplication::go() line 55 + 13 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00142436, HINSTANCE__ * 0x00000000) line 22
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 77e5eb69()
I am working on it for a few hours now. I can´t seem to find what I´m doing wrong.
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 67
Contact:

Post by sinbad »

All it's doing around line 365 is trying to retrieve a previously set up material. Non-default groups always work fine for me, we use 2 groups in all the standard demos. You must not be initialising that resource group properly, or at the right time, or the paths are wrong, or there's a problem with the scripts. Is there anything in Ogre.log? Set your debugger on the initialiseResourceGroup method and prove that it really is getting called for your custom group and that it's doing what you're expecting.
User avatar
spookyboo
Silver Sponsor
Silver Sponsor
Posts: 1141
Joined: Tue Jul 06, 2004 5:57 am
x 151
Contact:

Post by spookyboo »

Well, I figured it out and its working now.

1. I didn't realise that a material file defined in a certain group can only use textures from that group. Sharing textures between groups seems impossible (I think this can be solved by also adding the path containing 'shared textures' to the new group)
2. The TerrainSceneManager forces me to use the default group (method setWorldGeometry)

Code: Select all

// Clear out any existing world resources (if not default)
if (ResourceGroupManager::getSingleton().getWorldResourceGroupName() != 
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)
{
            ResourceGroupManager::getSingleton().clearResourceGroup(
            ResourceGroupManager::getSingleton().getWorldResourceGroupName());
}
I didn't want that, so I commented the clear part. This seems to fix the problem

3. I also had to load the material before calling setWorldGeometry

Code: Select all

MaterialManager::getSingleton().load (projectMaterial, projectName);
The TerrainSceneManager searches the material by name and apparently it returns null (well, the isNull method does) if the material isn't loaded first
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 67
Contact:

Post by sinbad »

spookyboo wrote: 1. I didn't realise that a material file defined in a certain group can only use textures from that group. Sharing textures between groups seems impossible (I think this can be solved by also adding the path containing 'shared textures' to the new group)
Once loaded, resources can freely be shared among groups. However, if you try to use a texture which is not in your group's resource locations, and the texture isn't loaded yet, of course it can't find it. Mixing & matching resources from different groups once they're loaded is fine, but be careful since unloading happens on group boundaries. If you're sharing a lot, perhaps you haven't structured your groups in a practical way - they should be grouping resources which have a common use.
2. The TerrainSceneManager forces me to use the default group (method setWorldGeometry)

Code: Select all

// Clear out any existing world resources (if not default)
if (ResourceGroupManager::getSingleton().getWorldResourceGroupName() != 
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)
{
            ResourceGroupManager::getSingleton().clearResourceGroup(
            ResourceGroupManager::getSingleton().getWorldResourceGroupName());
}
I didn't want that, so I commented the clear part. This seems to fix the problem
No, it's not forcing you to use the default. Look at the code again - it's firstly checking to see if the 'world resource group' is set to the default group. If it is, it does nothing. If, however the world resource group has been set to something dedicated, it clears the resource group out since it knows that the group is dedicated to it's world geometry.
3. I also had to load the material before calling setWorldGeometry

Code: Select all

MaterialManager::getSingleton().load (projectMaterial, projectName);
The TerrainSceneManager searches the material by name and apparently it returns null (well, the isNull method does) if the material isn't loaded first
Again this is because you're not structuring your groups along natural loading batch lines. What's happened is that you've put the material in another group so it can't locate it unless it's already loaded. If you want the terrain to use another group, call ResourceGroupManager::setWorldResourceGroupName to tell it which to use. If you're mixing and matching world resource groups and different material resource groups such that you have to force pre-loading, I'd have to ask why - if the material is for the terrain it should be in the same group, or if it's shared among lots of things, put it in a preloaded Common group.
User avatar
spookyboo
Silver Sponsor
Silver Sponsor
Posts: 1141
Joined: Tue Jul 06, 2004 5:57 am
x 151
Contact:

Post by spookyboo »

I still don't see it :( , maybe I have to put it aside for a while. I have been adding my material and textures in a dedicated group and have been calling setWorldResourceGroupName. Then the clearResourceGroup method in the TerrainSceneManager removes my loaded material again, because the group != DEFAULT_RESOURCE_GROUP_NAME

So, basicly I can only make it work if I make a small change to the TerrainSceneManager (and that was the whole point, I didn´t want that)

Sinbad, thanks for your patience.
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 67
Contact:

Post by sinbad »

I still don't see it Sad , maybe I have to put it aside for a while. I have been adding my material and textures in a dedicated group and have been calling setWorldResourceGroupName. Then the clearResourceGroup method in the TerrainSceneManager removes my loaded material again, because the group != DEFAULT_RESOURCE_GROUP_NAME
That's kind of the point. By calling setWorldResourceGroupName you're saying that that's the resource group which all the world resources wil be in, and that when the world group is cleared, they get cleared too. If you don't want the material cleared then it shouldn't be in the same group as the world resources, simple as that. You'll need to put it in another more persistent group which is initialised before you call setWorldGeometry.

The point here is that if the material is in the same custom world resource group, it allows you to have completely different world geometry with individual materials per world geometry set. Since they must be disjoint from any other group you could even call the files the same thing in every case (the material scripts, the terrain.cfg, everything). For example you could attach a self-contained ZIP which included everything you needed for that 'level'. Of course, if you're using a custom resource group you have to make sure you initialise it to parse all the scripts before calling setWorldGeometry.

You seem to want to use the same material resource across more than one level, but you're putting it in a the world resource group which gets cleared when the world geometry does, so this is not the way to do it. I think you're getting mixed up between loading / lifespan and usage - you don't have to put the material in the world resource group for it to be available, it just has to be in a group which is initialised by the time you call setWorldGeometry. Putting the material resource in the world resource group means it has the same lifespan as the world geometry resources, as you've discovered.

To reiterate - resource groups are there for controlling the lifecycle of resources, when they are initialised, where they can be loaded from, when they die. It does not limit dependencies between groups, but if you have a resource in one group relying on a resource in another, you have to make sure the latter exists whilst the former does.
User avatar
spookyboo
Silver Sponsor
Silver Sponsor
Posts: 1141
Joined: Tue Jul 06, 2004 5:57 am
x 151
Contact:

Post by spookyboo »

I get it now. I was a bit overwhelmed because of all resource management changes, and had to find my way in it. I must say it is exactly what I needed. Good job.
I have a dedicated resourcegroup for the terrain. I want the heigthmap be part of it, but as far I can tell it tries to load the heightmap in the WorldResourceGroup (maybe I screwed up the TerrainSceneManager by now)
Post Reply