Background loading problem

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
Post Reply
User avatar
wpc062
Gnoblar
Posts: 4
Joined: Thu Feb 01, 2007 3:42 am
Location: Wuhan,China

Background loading problem

Post by wpc062 »

I'm making a test by using OGRE and not quite knowing the complex Material System. :?
Now I design a class

Code: Select all

QuadTile : public Renderable, public Resource::Listener
, and want to use background thread for loading terrains and images , some code is below:

Code: Select all

void QuadTile::_fireMaterialBackgroundRequest(void)
	{
		mpTexture = static_cast<TexturePtr>(TextureManager::getSingleton().create("BumpyMetal.jpg",ResourceGroupManager::
			INTERNAL_RESOURCE_GROUP_NAME));
		mpTexture->setBackgroundLoaded(true);
		mpTexture->addListener(this);
		//Background loading
		ResourceBackgroundQueue* rbq = ResourceBackgroundQueue::getSingletonPtr();		
		
		rbq->load("Texture" ,mpTexture->getName(),ResourceGroupManager::
			INTERNAL_RESOURCE_GROUP_NAME,false,0,0,0);			
				
		return ;
	}
void QuadTile::backgroundLoadingComplete(Resource* res) 
	{
		if(res == mpTexture.get())
		{
			_initialise();
		}
	}
My question is: When the corresponding image is loaded, I can't get a notification and the function Resource::Listener::backgroundLoadingComplete(Resource* res) isn't implemented. It means that the code such as

Code: Select all

if (mIsBackgroundLoaded)
    queueFireBackgroundLoadingComplete(); 
in function
void Resource::load(bool background) doesn't run rightly.
Can someone tell me why and how to do correctly ? :)
Last edited by wpc062 on Sat Mar 17, 2007 2:57 pm, edited 2 times in total.
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 66
Contact:

Post by sinbad »

Did you actually compile ogre with OGRE_THREAD_SUPPORT set to 1 in OgreConfg.h?
User avatar
wpc062
Gnoblar
Posts: 4
Joined: Thu Feb 01, 2007 3:42 am
Location: Wuhan,China

Post by wpc062 »

sinbad wrote:Did you actually compile ogre with OGRE_THREAD_SUPPORT set to 1 in OgreConfg.h?
Thanks for your so quick reply!
Oh, yes. I think the main problem is how i add the
QuadTile : public Resource::Listener to the Resource.
When I use

Code: Select all

texUS->_getTexturePtr()->addListener(this);
the texture actually has been loaded.
User avatar
wpc062
Gnoblar
Posts: 4
Joined: Thu Feb 01, 2007 3:42 am
Location: Wuhan,China

Post by wpc062 »

I think i have solved the problem by testing the code all day long.
There may be something wrong in OgreResourceManager.cpp

By testing Playpen I find that when i am using Backgroud thread for loading Resource, Resource::setBackgroundLoaded(bool bl) and Resource::escalateLoading() have never been used at all. Maybe the problem is because
ResourcePtr ResourceManager::load(const String& name,
const String& group, bool isManual, ManualResourceLoader* loader,
const NameValuePairList* loadParams)
,
so i change the function as below:

Code: Select all

ResourcePtr ResourceManager::load(const String& name, 
        const String& group, bool isManual, ManualResourceLoader* loader, 
        const NameValuePairList* loadParams)
    {
        ResourcePtr ret = getByName(name);
        if (ret.isNull())
        {
            ret = create(name, group, isManual, loader, loadParams);
        }
		// ensure loaded
       // ret->load(); //
        if(ret->isBackgroundLoaded())
			ret->escalateLoading();
		else
			ret->load();
        return ret;
    }
Finally the Resource::Listener works correctly.

By the way, there still is a problem:
I must declare some Resorce will be loaded in background by using Resource::setBackgroundLoaded(bool bl) at first, while Background thread forget or miss the misson. :)
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 66
Contact:

Post by sinbad »

Ok, I'll log this. Generally the resource background loading is used for loading entire resources that are only declared, not actually created so this area probably hasn't been covered as well.

Bear in mind that you could use ResourceBackgroundQueue::Listener to listen in on the result of any background thread request.
User avatar
wpc062
Gnoblar
Posts: 4
Joined: Thu Feb 01, 2007 3:42 am
Location: Wuhan,China

Post by wpc062 »

sinbad wrote:Ok, I'll log this. Generally the resource background loading is used for loading entire resources that are only declared, not actually created so this area probably hasn't been covered as well.

Bear in mind that you could use ResourceBackgroundQueue::Listener to listen in on the result of any background thread request.
Thanks a lot for your advice.
But my project,which is something like Google Earth but now is much weaker than it, divides a big sphere (Earth) into many Tiles (terrains + images), and when the main camera moves close to the Earth visible Tiles may be cutted into more Tiles (more detailed terrains and images) by using quadtree recursion. So every Tile must send a resource request to Backgroud thread, and when a resource is downloaded, the corresponding Tile must initialise and in the next rendering cycle it can be rendered. So every resource request and response are run-time and tile must deal with these things separately.
When I finish my test ,i will show the result and hope it's useful. :)
psquare
Hobgoblin
Posts: 554
Joined: Tue Nov 14, 2006 3:26 pm
x 7

Post by psquare »

Sorry to dig up this old thread, but I am having the same problem:

I want to load a bunch of textures one by one, and I want to receive notification about when they are done via backgroundLoadingComplete

I can't really use operationCompleted callback, because that only gives me the ID. I want to know which resource was loaded.

However, backgroundLoadingComplete is never called because setBackgroundLoaded(true) is never called on the resource.

Manually calling setBackgrounLoaded(true) doesn't work either because the calling thread does not call Resource::load(bool background) with background set to true.

I looked at head on CVS (I am using 1.4.7) but there doesn't seem to be a difference in the pertinent code at the same place.

What's the correct way to fix this?
psquare
Hobgoblin
Posts: 554
Joined: Tue Nov 14, 2006 3:26 pm
x 7

Post by psquare »

Any ideas?
Shareth
Gnoblar
Posts: 13
Joined: Tue Aug 21, 2007 7:29 am

Post by Shareth »

We've been investigating the very same problem. It appears Ogre doesn't call Resource::load(true) anywhere in its code at all. wpc062's patch to ResourceManager::load() works and solves part of the problem, but not everything. It works perfectly for meshes, but if you try to load material in a background, material loads all associated textures which in turn are loaded with Resource::load(false). I don't know any simple way to pass that 'true' to load() besides the very first one called inside ResourceManager::load(). To solve this, you have to manually run through all the techniques in material and queue their load in background thread one by one. Something tells me all that could be done inside Ogre automatically.

For example this kind of behavior could be implemented:
1. Call createEntity() -> Ogre automatically queues load of mesh, if its not loaded yet.
2. Call setMaterialName() on new entity -> Ogre automatically queues load of material and all associated textures and stuff, if its not loaded yet.
3. When all the stuff is loaded, it is displayed automatically.

All this could be controlled via some kind of switch in resource manager or something that defines if we should automatically load stuff in background thread or not, what stuff should be loaded in background and such.

From my experience as a user similar behavior is implemented in WoW. If your machine is slow and you just entered the game you might see lots of shadows of other players running around but no player models. All of them load slowly one by one. If your machine is very slow, you might even see how the entire level (terrain, buildings, etc) is being loaded. And all this happens without a single hitch or loss of response from user's point of view so it is obviously loaded in background.

IMHO Ogre could greatly benefit from this kind of feature.
Post Reply