[osg-users] Issue on sharing shaders between objects

Christian Heine Hellhound at binary-revolution.org
Fri Jun 6 07:39:44 PDT 2008


Hello,

i've played arround again with this issue and now i am totally 
confused :o(

I (re-)implemented a test where i set all values new explicit for the 
osg::StateSet of the objects (checked the values, the states are 
differend) by this way:

void OSGEffect::attach(osg::ref_ptr<osg::StateSet> state)
{
// create program, add attributes
osg::ref_ptr<osg::Program> prg = new osg::Program;
prg->addBindAttribLocation("tangent", osg::Drawable::ATTRIBUTE_6);
prg->addBindAttribLocation("binromal", osg::Drawable::ATTRIBUTE_7);

// load config
boost::shared_ptr<OSGTechnique> technique =
this->getOSGTechnique(AbstractTechnique::VERSION_PS30);

//create shader
boost::shared_ptr<config::ITechnique> config = 	technique->getConfig();
config::ITechnique::shaders_t list = config->getShaders();

for(config::ITechnique::shaders_t::iterator shaderIter = list.begin();
     shaderIter != list.end();
     shaderIter++){

// create a renderable shader based on the configuration
  boost::shared_ptr<AbstractShader> shader = 
AbstractShaderFactory::getInstance().createShader(
 
AbstractShaderFactory::getInstance().getShaderConfig((*shaderIter)->getFile()));

// cast to OSGGLSLShader
boost::shared_ptr<OSGGLSLShader> 
osgShader(boost::dynamic_pointer_cast<OSGGLSLShader>(shader));
utils::Assert<IllegalCastException>( osgShader!=0,
   "[OSGTechnique]::initialize: Dynamic cast of OSGGLSLShader is 
invalid!");

prg->addShader(osgShader->getShader().get());
}

// create and add uniforms
osg::Uniform* lightPosU = new osg::Uniform("LIGHT_POSITION", 
osg::Vec4(10.0, 0.0, 0.0, 1.0));
state->addUniform(lightPosU, osg::StateAttribute::ON | 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);

osg::Uniform* cameraPosU = new osg::Uniform("CAMERA_POSITION", 
osg::Vec3(0.0, -110.0, 0.0));
state->addUniform(cameraPosU, osg::StateAttribute::ON | 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);

osg::Uniform* lightRadius = new osg::Uniform("lightRadius", 10.0f);
state->addUniform(lightRadius, osg::StateAttribute::ON | 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);

osg::Uniform* normalMapU = new osg::Uniform("normalMap",1);
state->addUniform(normalMapU, osg::StateAttribute::ON | 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);

osg::Uniform* baseTextureU = new osg::Uniform("decalMap",0);
state->addUniform(baseTextureU, osg::StateAttribute::ON | 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);

osg::Uniform* ambientU = new osg::Uniform("matAmbient", 
osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
state->addUniform(ambientU, osg::StateAttribute::ON | 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);

osg::Uniform* diffuseU = new osg::Uniform("matDiffuse", 
osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f));
state->addUniform(diffuseU, osg::StateAttribute::ON | 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);

osg::Uniform* specularU = new osg::Uniform("matSpecular", 
osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f));
state->addUniform(specularU, osg::StateAttribute::ON | 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);

// bind all to state
state->setAttributeAndModes(prg.get(), osg::StateAttribute::ON);
}

I got the same issue. All shading effects are equal on differend 
objects and differnd StateSets. Has anyone an idea what could be wrong 
before i get completly nuts?

Best regards,
Christian










Christian Heine wrote:
> Hi Mike,
> 
> thanks for the hint, but this is not the failure. This is the normal way 
> to bind the program to the different state sets and it works.
> 
> Meenwhile I think that I've a problem with the actualization of the 
> program and/or shaders. So I've called the setDirty methods on all
> but with no positive result ...
> 
> Best regards,
> Christian
> 
> 
> 
> Mike Weiblen wrote:
>> This caught my eye:
>>
>>>      state->setAttributeAndModes(prg.get(), osg::StateAttribute::ON);
>>>  }
>>>  // otherwise bind the program and deactivate it.
>>>  else{
>>>      state->setAttributeAndModes(m_program.get(),
>> osg::StateAttribute::OFF);
>>>  }
>>
>> osg::StateAttribute::ON/OFF does not work on osg::Program, as GL does
>> not use glEnable/glDisable on glPrograms.  GL disables an active
>> glProgram with glUseProgram(0); the equiv in OSG is to attach an "empty"
>> osg::Program (one that has no osg::Shaders attached)  Perhaps that is
>> confusing the OSG state manager, causing this failure?
>>
>> -- mew
>>
>>
>>
>>> -----Original Message-----
>>> From: osg-users-bounces at lists.openscenegraph.org [mailto:osg-users-
>>> bounces at lists.openscenegraph.org] On Behalf Of Christian Heine
>>> Sent: Thursday, June 05, 2008 11:34 AM
>>> To: OpenSceneGraph Users
>>> Subject: Re: [osg-users] Issue on sharing shaders between objects
>>>
>>> Hello,
>>>
>>> i've played arround with this issue, but i could solve it until now.
>>> First i thought there may be a problem with the reusage of the
>>> program, but when i copy it instead of sharing, nothing happends, i
>>> got the same failure.
>>>
>>>     // finaly bind the program and activate it if it is user enabled
>>>          if(this->m_userEnabled){
>>>
>>>              for(uniforms_t::iterator uniIter =
>> m_uniformCache.begin();
>>>                  uniIter != m_uniformCache.end();
>>>                  uniIter ++){
>>>                  // add all uniforms from the list to the state
>>>                  state->addUniform((*uniIter).second.get(),
>>> osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE |
>>> osg::StateAttribute::PROTECTED);
>>>              }
>>>
>>>         /* fake for copy program
>>>              osg::ref_ptr<osg::Program> prg = new osg::Program;
>>>              prg->addBindAttribLocation("tangent",
>>> osg::Drawable::ATTRIBUTE_6);
>>>              prg->addBindAttribLocation("binromal",
>>> osg::Drawable::ATTRIBUTE_7);
>>>
>>>              boost::shared_ptr<OSGTechnique> technique =
>>>              this->getOSGTechnique(AbstractTechnique::VERSION_PS30);
>>>
>>>              // convert BinRev shader params to osg::Uniform and
>>> osg::Attribute objects
>>>              for( unsigned int i = 0;
>>>                   i <  technique->getNumberOfShaders();
>>>                   i++)
>>>              {
>>>                  boost::shared_ptr<OSGGLSLShader> shader =
>>>
>>> boost::dynamic_pointer_cast<OSGGLSLShader>(technique->getShader(i));
>>>                  prg->addShader(shader->getShader().get());
>>>              }
>>>         */
>>>
>>>              state->setAttributeAndModes(prg.get(),
>>> osg::StateAttribute::ON);
>>>          }
>>>          // otherwise bind the program and deactivate it.
>>>          else{
>>>              state->setAttributeAndModes(m_program.get(),
>>> osg::StateAttribute::OFF);
>>>          }
>>>      }
>>>
>>> There is nothing realy special...
>>> I've attached an image to show what's going wrong.
>>>
>>> Has anyone a hint what could be going wrong? I'm running out of
>> ideas..
>>> Best regards,
>>> Christian
>>>
>>>
>>>
>>>
>>>
>>>
>>> hellhound at binary-revolution.org wrote:
>>>> Hello,
>>>>
>>>> i've successfully implemented a simple dot3 object shading for my
>>> scene and
>>>> it works fine with single objects. Now i try to share the shaders
>>> between
>>>> different objects in the scene and got some trouble:
>>>>
>>>> To share the shaders i've one osg::Program, where i've added two
>>> osg::Shader
>>>> objects. The osg::Program instance is shared between the objects and
>>> applied
>>>> to their osg::StateSet objects. The required osg::Uniform objects
>> are
>>> created
>>>> explicit for each object and bind to their osg::StateSet in a
>>> separated process.
>>>> So only the osg::Program and osg::Shader are Shared (later i will
>>> share the
>>>> equal uniforms too).
>>>>
>>>> The shader works, but it's effected on all objects equals to the
>>> object where
>>>> the osg::Program has applied first. I.e. i've added two normal
>> mapped
>>> cubes in
>>>> the scene. When i set the light between both cubes i expect that
>> both
>>> cube faces
>>>> are enlighted arround the light, but on the 2nd cube the thame face
>>> of the first
>>>> cube is enlighted...
>>>>
>>>> Have i consider something special for the sharing of (object)
>> shaders
>>> between
>>>> objects?
>>>>
>>>> Best regards,
>>>> Christian
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> osg-users mailing list
>>>> osg-users at lists.openscenegraph.org
>>>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-
>>> openscenegraph.org
>>
>> _______________________________________________
>> osg-users mailing list
>> osg-users at lists.openscenegraph.org
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>
> 
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: failure1.png
Type: image/png
Size: 332612 bytes
Desc: not available
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20080606/4a4526df/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: failure2.png
Type: image/png
Size: 192809 bytes
Desc: not available
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20080606/4a4526df/attachment-0003.png>


More information about the osg-users mailing list