Reparsing *.material files.

Problems building or running the engine, queries about how to use features etc.
Post Reply
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 997
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 48
Contact:

Reparsing *.material files.

Post by Crashy »

Hello,
Fast but clear question:
Is there another more specific way to reload material scripts/shaders than unload and reload the resource groups?

Thanks:)
Follow la Moustache on Twitter or on Facebook
Image
User avatar
vitefalcon
Orc
Posts: 438
Joined: Tue Sep 18, 2007 5:28 pm
Location: Seattle, USA
x 13

Re: Reparsing *.material files.

Post by vitefalcon »

Quick answer, there isn't a straight-forward method to do what you want. However there is a way to reload specify material scripts, which I shall post once I am home.
Image
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 997
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 48
Contact:

Re: Reparsing *.material files.

Post by Crashy »

This is fine too, thanks.
Follow la Moustache on Twitter or on Facebook
Image
User avatar
vitefalcon
Orc
Posts: 438
Joined: Tue Sep 18, 2007 5:28 pm
Location: Seattle, USA
x 13

Re: Reparsing *.material files.

Post by vitefalcon »

Hi Crashy,

I'm attaching a code dump of what I have. It's taken from HOWTO: Reloading materials and parsing material scripts. However, the code in this file has some modifications that helped me get over some problems especially the function 'UpdateSceneManagersForMaterialChange()' function. I haven't added these changes to wiki, but you're free to do so.

Hope this is what you needed.
Attachments
OgreHelper.zip
Helper functions for reloading Ogre3D material.
(2.88 KiB) Downloaded 229 times
Image
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 997
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 48
Contact:

Re: Reparsing *.material files.

Post by Crashy »

Thanks a lot!
Follow la Moustache on Twitter or on Facebook
Image
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 997
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 48
Contact:

Re: Reparsing *.material files.

Post by Crashy »

I've had time to test the code, and after a bug fix in the DX11 rendersystem, it doesn't crash anymore.
However, if I change the material, the changes aren't visible. For example, if I change the texture file of a texture unit, although the old texture is unloaded and the new texture loaded, there is no difference on screen.

Notice I call your function UpdateSceneManagersForMaterialChange
Before goint into deep investigation, is there anything I should have missed to make it work properly.

Thanks.
Follow la Moustache on Twitter or on Facebook
Image
User avatar
vitefalcon
Orc
Posts: 438
Joined: Tue Sep 18, 2007 5:28 pm
Location: Seattle, USA
x 13

Re: Reparsing *.material files.

Post by vitefalcon »

Crashy wrote:Notice I call your function UpdateSceneManagersForMaterialChange
Do you only call UpdateSceneManagersForMaterialChange() or do you reload the material file and then call this function?
Image
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 997
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 48
Contact:

Re: Reparsing *.material files.

Post by Crashy »

I reload the material file and then call this function .
Follow la Moustache on Twitter or on Facebook
Image
User avatar
vitefalcon
Orc
Posts: 438
Joined: Tue Sep 18, 2007 5:28 pm
Location: Seattle, USA
x 13

Re: Reparsing *.material files.

Post by vitefalcon »

I was using this with 1.4.7, which version of Ogre are you using? I'll try digging deeper once I'm home.
Image
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 997
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 48
Contact:

Re: Reparsing *.material files.

Post by Crashy »

Don't spend too much time on your side for me, I can do it, but not right now, I 've got other things to do before.

I use a Ogre 1.8 unstable and DX11 rendersystem.

Thank you for your help and snippet, it is clearly a good start point for me.
Follow la Moustache on Twitter or on Facebook
Image
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 997
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 48
Contact:

Re: Reparsing *.material files.

Post by Crashy »

I've finally got the time to check what was wrong.

When reloading the material, the material I get by doing "Ogre::MaterialManager::getSingleton().getByName("aName")" is updated with the modifications made to the material script.

But the material I get doing "entity->getSubEntity(0)->getMaterial()", even if it has the same name, is not updated and becomes different from the material I get from the material manager.

If my understanding is good, this is what appens:

-The material is "unloaded" by the material manager, but still referenced by the entities using it.
-When reloading the material, the material manager has no reference to a material of that name, so it creates a new material.
-The new material is reflecting the content of the .material file.
-But the entity still has the old material, it is not aware the new material.
-I have finally two materials of the same name loaded, and one of them is not referenced by the material manager.


How to fix this apart from parsing all entities of my scene, check which one has a link to the reloaded material and change this link.
Follow la Moustache on Twitter or on Facebook
Image
def87
Halfling
Posts: 90
Joined: Wed Sep 19, 2012 1:41 pm
x 1

Re: Reparsing *.material files.

Post by def87 »

reviving this thread...
Crashy wrote: If my understanding is good, this is what appens:

-The material is "unloaded" by the material manager, but still referenced by the entities using it.
-When reloading the material, the material manager has no reference to a material of that name, so it creates a new material.
-The new material is reflecting the content of the .material file.
-But the entity still has the old material, it is not aware the new material.
-I have finally two materials of the same name loaded, and one of them is not referenced by the material manager.


How to fix this apart from parsing all entities of my scene, check which one has a link to the reloaded material and change this link.
I am having the same problem when reloading a resource by its ResourcePtr, such as a material by name, the material used on screen stayes unchanged.
Is the Resource Manager not responsible for updating entities that use this resource?
bstone
OGRE Expert User
OGRE Expert User
Posts: 1920
Joined: Sun Feb 19, 2012 9:24 pm
Location: Russia
x 199

Re: Reparsing *.material files.

Post by bstone »

Yes, apparently it's not. It would have been a great overhead to track all entities using a resource when the only use case that requires that is rather uncommon. You can still work around that by reassigning new materials to all affected entities.
def87
Halfling
Posts: 90
Joined: Wed Sep 19, 2012 1:41 pm
x 1

Re: Reparsing *.material files.

Post by def87 »

Ok, now I am totally confused:

I have a mesh with 5 submeshes, each with a different material.

Code: Select all

Ogre::ResourcePtr rPtr = Ogre::MaterialManager::getSingletonPtr()->load(resourceName, "General");
rPtr->reload();
Does not change anything on screen, <resourceName> being a material name.
Calling setMaterialName() with a different material name on all submeshed does nothing on screen as well.

Now the weird part:

Calling getMaterialName() will now return the new material name for all submeshes.
Going through all material definition via

Code: Select all

myEntity->getSubEntity(index)->getMaterial()
reports material values of the original material, not the changed on...

What am I missing?
bstone
OGRE Expert User
OGRE Expert User
Posts: 1920
Joined: Sun Feb 19, 2012 9:24 pm
Location: Russia
x 199

Re: Reparsing *.material files.

Post by bstone »

You have to update all sub-entities, not sub-meshes.
def87
Halfling
Posts: 90
Joined: Wed Sep 19, 2012 1:41 pm
x 1

Re: Reparsing *.material files.

Post by def87 »

bstone wrote:You have to update all sub-entities, not sub-meshes.
Yes, thanks, I assume the mesh materials are copied to the entity on creation.

So, changing a material now works. :)
Only updating the material resource by calling reload() still does not work...
bstone
OGRE Expert User
OGRE Expert User
Posts: 1920
Joined: Sun Feb 19, 2012 9:24 pm
Location: Russia
x 199

Re: Reparsing *.material files.

Post by bstone »

As I said, reload() will not work, you will have to go through all sub-entities and change their materials to "BaseWhite", then call reload(), then go once again through all your sub-entities and assign their materials back to them.
def87
Halfling
Posts: 90
Joined: Wed Sep 19, 2012 1:41 pm
x 1

Re: Reparsing *.material files.

Post by def87 »

This is my code, reloading the resource still does not work:

Do I need to call reload() somewhere else?

Code: Select all

Ogre::Entity* pEnt = m_pSceneMgr->getEntity("dummy");

int nMaxSubEntity = pEnt->getNumSubEntities();

for(int SubEntity=0 ; SubEntity<nMaxSubEntity ; SubEntity++)
	pEnt->getSubEntity(SubEntity)->setMaterialName("BaseWhite");

Ogre::ResourcePtr rPtr = Ogre::MaterialManager::getSingletonPtr()->load(resourceName, "General");
rPtr->unload();

for(int SubEntity=0 ; SubEntity<nMaxSubEntity ; SubEntity++)
	pEnt->getSubEntity(SubEntity)->setMaterialName(resourceName);
bstone
OGRE Expert User
OGRE Expert User
Posts: 1920
Joined: Sun Feb 19, 2012 9:24 pm
Location: Russia
x 199

Re: Reparsing *.material files.

Post by bstone »

Why would you unload the material right after loading it? Have you tried doing it the opposite way?
def87
Halfling
Posts: 90
Joined: Wed Sep 19, 2012 1:41 pm
x 1

Re: Reparsing *.material files.

Post by def87 »

:?:

Lets assume resourceName = "ShinyMaterial"

So, I am doing:

1. setMaterialName("BaseWhite");
2. Resource "ShinyMaterial" reload()
3. setMaterialName("ShinyMaterial");
bstone
OGRE Expert User
OGRE Expert User
Posts: 1920
Joined: Sun Feb 19, 2012 9:24 pm
Location: Russia
x 199

Re: Reparsing *.material files.

Post by bstone »

This:

Code: Select all

Ogre::ResourcePtr rPtr = Ogre::MaterialManager::getSingletonPtr()->load(resourceName, "General");
rPtr->unload();
is "load, then unload" whereas reload() would at least be "unload, then load again", no?
def87
Halfling
Posts: 90
Joined: Wed Sep 19, 2012 1:41 pm
x 1

Re: Reparsing *.material files.

Post by def87 »

:?
I was expecting a pointer back from the load function if it was already loaded...

This is what I should use:
Ogre::ResourcePtr rPtr = Ogre::MaterialManager::getSingletonPtr()->getByName( resourceName );
pPtr->reload()
Still nor working...

I have only one Mesh loaded with one SubMesh.
rPtr gives me a reference count of 5! Which should be 1, right?

After
setMaterialName("BaseWhite");
the count goes to 4.
Re setting the MaterialName to the same name increases the counter to 5.

What is referencing my material and how can I find any references?
Post Reply