Reload material with shaders

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Reload material with shaders

Post by lordsme »

Hi everyone,
after some effort I finally managed to use the Wiki's code snippet about material reloading:
http://www.ogre3d.org/wiki/index.php/Re ... al_scripts

By the way if I reload materials that contains shaders, after the reloading the vertex positions become "bugged"...
I mean, if I move the camera, the vertex remains always in the same position, as if they were parented to the camera...
Have you got any idea?
After reloading the material I had to assign again the material to the sub-entities, otherwise no update was visible.
Thank you


Dav
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

I find that the shader lose all the binding with the automated params: lights, matrices, etc etc.
Everything has been freezed at the moment I reloaded the material...
How to restore these bindings?
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

No idea??
I canìt fnd any suggestion on the web or in the API docs..
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: Reload material with shaders

Post by madmarx »

Just put it in a resource group, and reload the resource group. That should do the trick. Other wise , just you can try my helper :
http://www.ogre3d.org/forums/viewtopic. ... 25#p329272
I don't know if it works on ogre 1.7 though.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

I use OGRE 1.6.5.
By the way, I can't understand very well what you said...

I use this helper method in the wiki:

void ReloadMaterial(const std::string& materialName, const std::string& groupName, const std::string& filename, bool parseMaterialScript)

on the .material that contains the material definition and on the imported .program that contains the program references, etc.
By the way, also if I reload these materials, the bindings (param_named_auto) get broken and matrices, light positions, etc are no longer updated...
:( :?
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: Reload material with shaders

Post by madmarx »

If you don't know what is a resource or a resourcegroup, you should check the tutorials.
The class I gave in previous post has allowed other people & myself to do realtime shader / compositor edition (because the one of the wiki was not good for me). On Ogre1.6.5 it works, and I also gave code examples.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

I'm still trying to get this code to work with shaders:
http://www.ogre3d.org/tikiwiki/Reloadin ... al+scripts

As I said before, auto parameters bindings are lost once the shaders are reloaded.
Anyone ever found a solution for this problem, using this cookbook snippet?

Thank you
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

madmarx wrote:Just put it in a resource group, and reload the resource group. That should do the trick. Other wise , just you can try my helper :
http://www.ogre3d.org/forums/viewtopic. ... 25#p329272
I don't know if it works on ogre 1.7 though.
Doing this doesn't solve the auto params bindings problem... I still lose them.
:?: :?: :?:
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: Reload material with shaders

Post by madmarx »

Ok, thanks for the info, I will have to dig this.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

I'm trying to do the same with compositors, and this works a little better:

Code: Select all

// reload the compositor resource group
Ogre::CompositorPtr compositor = Ogre::CompositorManager::getSingletonPtr()->getByName(m_compositorName);
Ogre::ResourceGroupManager::getSingletonPtr()->unloadResourceGroup(compositor->getGroup());
Ogre::ResourceGroupManager::getSingletonPtr()->loadResourceGroup(compositor->getGroup());
By the way it works only 1 time: when I try to do it again, the second time, OGRE crashes and the log is stopped at:

Code: Select all

...
10:18:51: Unloading resource group PostFilters
10:18:51: Finished unloading resource group PostFilters
10:18:51: Loading resource group 'PostFilters' - Resources: 1 World Geometry: 1
10:18:51: Finished loading resource group PostFilters
10:18:54: OGRE EXCEPTION(2:InvalidParametersException): Parameter called EPF_HSLReference does not exist.  in GpuProgramParameters::_findNamedConstantDefinition at f:\codingextra\ogre\shoggoth_vc9\ogre\ogremain\src\ogregpuprogram.cpp (line 1097)
10:18:54: OGRE EXCEPTION(2:InvalidParametersException): Parameter called EPF_Weight does not exist.  in GpuProgramParameters::_findNamedConstantDefinition at f:\codingextra\ogre\shoggoth_vc9\ogre\ogremain\src\ogregpuprogram.cpp (line 1097)
10:19:09: Unloading resource group PostFilters
10:19:09: Finished unloading resource group PostFilters
10:19:09: Loading resource group 'PostFilters' - Resources: 1 World Geometry: 1
Any idea why it happens? :x
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

Well, looking around in the APIs and the forum, I have some doubt.

I'm trying to reload compositors and material shaders to develop them interactively when OGRE is running.
I read in the APIs and the forum that unloading and reloading a resource group should not recompile shaders (which are compiled at resource group initialization?)... but it works! If I change the source code of a compositor Cg shader, I do see the updated compositor if I just unload and load its resource group (when it's disabled or enabled).
By the way if I do it more than one time, OGRE crashes...
:?:
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

I tried also

Code: Select all

compositor->reload();
but doesn't work at all.
Any idea? :(
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

Still cannot find a solution!
:shock:
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
Caphalor
Greenskin
Posts: 116
Joined: Tue Feb 06, 2007 8:54 pm
Location: Berlin, Germany
x 25

Re: Reload material with shaders

Post by Caphalor »

One possible solution that I use, but it reloads all compositors:
1. disable all your enabled compositors
2. call Ogre::CompositorManager::getSingleton().removeAll();
3. reload the "compositor" resource group (I simply reload "General"):

Code: Select all

	Ogre::ResourceGroupManager::getSingleton().clearResourceGroup(resGroup);
	Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup(resGroup);
4. call Ogre::CompositorManager::getSingleton().initialise();
5. Add and enable your compositors (as you did during startup)

When reloading the "General" resource group, you also have to call Ogre::ParticleSystemManager::getSingleton().removeAllTemplates() before reloading. I also call Ogre::GpuProgramManager::getSingleton().removeAllSharedParameterSets(), but this is a method I added to Ogre (you only need it if you use shared parameter sets).
Image
Generated with vBaum - voxel based procedural geometry generator with python interface.
Amadeus
Gnoblar
Posts: 5
Joined: Fri May 26, 2006 7:22 pm
Location: France
x 2

Re: Reload material with shaders

Post by Amadeus »

To re-compile only a shader without re-parsing all materials or unloading it, I use: (I think it is the same for compositors)

Code: Select all

MaterialPtr mat = MaterialManager::getSingleton().getByName(Material");

mat->getTechnique(0)->getPass(0)->getVertexProgram()->setParameter("compile_arguments", "-DENABLE_XX_FEATURE");
mat->getTechnique(0)->getPass(0)->getVertexProgram()->escalateLoading();
mat->getTechnique(0)->getPass(0)->getVertexProgram()->reload();

mat->getTechnique(0)->getPass(0)->getFragmentProgram()->setParameter("compile_arguments", "-DENABLE_XX_FEATURE");
mat->getTechnique(0)->getPass(0)->getFragmentProgram()->escalateLoading();
mat->getTechnique(0)->getPass(0)->getFragmentProgram()->reload();
The important thing is the call to escalateLoading() before reload(), without this call I don't know why but nothing happens...
User avatar
toglia
Gnome
Posts: 336
Joined: Sat Dec 08, 2007 4:28 am
Location: Canada
x 7

Re: Reload material with shaders

Post by toglia »

Amadeus wrote:MaterialPtr mat = MaterialManager::getSingleton().getByName(Material");

mat->getTechnique(0)->getPass(0)->getVertexProgram()->setParameter("compile_arguments", "-DENABLE_XX_FEATURE");
mat->getTechnique(0)->getPass(0)->getVertexProgram()->escalateLoading();
mat->getTechnique(0)->getPass(0)->getVertexProgram()->reload();

mat->getTechnique(0)->getPass(0)->getFragmentProgram()->setParameter("compile_arguments", "-DENABLE_XX_FEATURE");
mat->getTechnique(0)->getPass(0)->getFragmentProgram()->escalateLoading();
mat->getTechnique(0)->getPass(0)->getFragmentProgram()->reload();
This works. But one more thing. It is somewhat common to have mistakes while developing shaders. So I've been trying to catch the Exceptions thrown by the *reload* method without luck.

Why would this still crash the app, I'm pretty sure the exception is thrown in this line.

Code: Select all

try{
mat->getTechnique(0)->getPass(0)->getFragmentProgram()->reload();
}catch(...){
qDebug() << "shader error";
}
The obvios best solution would be to handle Ogre's Exception, I've tried both, none seem to catch the internal error exception which is very weird!
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

madmarx wrote:Ok, thanks for the info, I will have to dig this.
A year or two have been passed... still none found a solution??
When I reload the shaders I still lose auto params bindings.

Thanks,
Davide
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
User avatar
lordsme
Gremlin
Posts: 167
Joined: Sun Mar 11, 2007 1:11 pm
Location: Turin, Italy
x 10
Contact:

Re: Reload material with shaders

Post by lordsme »

Damn, perhaps I finally found the trick...
just reset the fragment and vertex programs to passes and copy the parameters back...

Code: Select all

// once re-loaded the material,	
// to avoid losing shader parameter auto-bindings,
		// here we try to re-assign each fragment and vertex shader to their passes
		Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(materialName);
		Ogre::Material::TechniqueIterator techniqueIterator = material->getTechniqueIterator();
		while (techniqueIterator.hasMoreElements())
		{
			Ogre::Technique* technique = techniqueIterator.getNext();
			Ogre::Technique::PassIterator passIterator = technique->getPassIterator();
			while (passIterator.hasMoreElements())
			{
				Ogre::Pass* pass = passIterator.getNext();
				if(pass->hasVertexProgram())
				{
					std::string vert_program_name = pass->getVertexProgramName();
					// get original params
					Ogre::GpuProgramParametersSharedPtr vparamsSPtr = pass->getVertexProgramParameters();
					// save them for the moment
					Ogre::GpuProgramParameters old_vert_params;
					old_vert_params.copyConstantsFrom(*vparamsSPtr.getPointer());
					// re-assign the vertex shader and reset the params
					pass->setVertexProgram(vert_program_name, true);
					// copy the old ones back
					pass->getVertexProgramParameters()->copyConstantsFrom(old_vert_params);
				}
				if(pass->hasFragmentProgram())
				{
					std::string frag_program_name = pass->getFragmentProgramName();
					// get original params
					Ogre::GpuProgramParametersSharedPtr fparamsSPtr = pass->getFragmentProgramParameters();
					// save them for the moment
					Ogre::GpuProgramParameters old_frag_params;
					old_frag_params.copyConstantsFrom(*fparamsSPtr.getPointer());
					// re-assign the fragment shader and reset the params
					pass->setFragmentProgram(frag_program_name, true);
					// copy the old ones back
					pass->getFragmentProgramParameters()->copyConstantsFrom(old_frag_params);
				}
			}
		}
My Portfolio
http://davidedigiannantonio.weebly.com

MESH - Mise-en-scene Helper
http://www.mesh-project.org/

ASALab @ Virtual Reality & Multimedia Park
http://www.vrmmp.it
saephoed
Gnoblar
Posts: 1
Joined: Thu Jan 22, 2015 7:18 pm

Re: Reload material with shaders

Post by saephoed »

Knowing that it's been quite a while since this topic has been active, i tried the approach with Ogre 1.9 and had to explicitely clear the Microcode-Cache afterwards in order to get this to work:

Code: Select all

  std::string rs = "Vertex Program:Shooter/Shadertest3vp_glsl Fragment Program:Shooter/Shadertest3fp_glsl";
  GpuProgramManager::getSingleton().removeMicrocodeFromCache(rs);
Unfortunately, the approach is a hack because it relies on knowledge about the inner workings of the private method

Code: Select all

  Ogre::String GLSLLinkProgram::getCombinedName()
but i couldn't find another way and hope that this at least helps others to save some time.
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

Re: Reload material with shaders

Post by mrmclovin »

saephoed wrote:Knowing that it's been quite a while since this topic has been active, i tried the approach with Ogre 1.9 and had to explicitely clear the Microcode-Cache afterwards in order to get this to work:

Code: Select all

  std::string rs = "Vertex Program:Shooter/Shadertest3vp_glsl Fragment Program:Shooter/Shadertest3fp_glsl";
  GpuProgramManager::getSingleton().removeMicrocodeFromCache(rs);
Unfortunately, the approach is a hack because it relies on knowledge about the inner workings of the private method

Code: Select all

  Ogre::String GLSLLinkProgram::getCombinedName()
but i couldn't find another way and hope that this at least helps others to save some time.
Yes, I had the same problem and got to the same kind of solution as you did. I have a suggestion for a solution in the following thread: http://www.ogre3d.org/forums/viewtopic.php?f=2&t=82115
Post Reply