Hi Wojtek,

On Mon, May 11, 2009 at 10:06 PM, Wojciech Lewandowski
<[email protected]> wrote:
> Thanks for Warm welcome. If nothing interrupts me I will try tomorrow to add
> changes that Robert made and maybe will create more advanced example.

I've made more changes this morning :-)

First up I've moved the State::getAttributeVec() into the public
section along with the associated typedefs.  This is now checked into
svn/trunk.  Just in case you want to compile against other versions of
OSG, the version numbers are also updated in svn/trunk so now read
2.9.5 in prep for the next dev release.

Changed file is attached.

Once you are happy with this example how do you feel about it being
included as an OSG example?  It could then live on as a test bed for
this type of functionality in prep for introducing something similar
for doing shader composite into the core OSG later down the line.

Robert.
////////////////////////////////////////////////////////////////////////////////
#include<osg/Shader>
#include<osg/Program>
#include<osg/State>
#include<osg/Notify>
#include<cassert>
////////////////////////////////////////////////////////////////////////////////
#include<VirtualProgram.h>

using namespace osg;

#define MERGE_SHADERS 0

namespace osgExt {

////////////////////////////////////////////////////////////////////////////////
osg::Shader * VirtualProgram::getShader
    ( const std::string & shaderSemantic, osg::Shader::Type type )
{
    ShaderMap::key_type key( shaderSemantic, type );

    return _shaderMap[ key ].get();
}
////////////////////////////////////////////////////////////////////////////////
osg::Shader * VirtualProgram::setShader
( const std::string & shaderSemantic, osg::Shader * shader )
{
    if( shader->getType() == osg::Shader::UNDEFINED ) 
        return NULL;

    ShaderMap::key_type key( shaderSemantic, shader->getType() );

    ref_ptr< osg::Shader >   shaderNew     = shader;
    ref_ptr< osg::Shader > & shaderCurrent = _shaderMap[ key ];

//    shaderNew->setName( shaderSemantic );

    if( shaderCurrent != shaderNew ) {
#if 0
       if( shaderCurrent.valid() )
           Program::removeShader( shaderCurrent.get() );

       if( shaderNew.valid() )
           Program::addShader( shaderNew.get() );
#endif
       shaderCurrent = shaderNew;
    }

    return shaderCurrent;
}
////////////////////////////////////////////////////////////////////////////////
void VirtualProgram::apply( osg::State & state ) const
{
    State::AttributeVec *av = &state.getAttributeVec(this);

    std::ostream &os  = osg::notify( osg::INFO );

    os << "VirtualProgram cumulate Begin" << std::endl;

    ShaderMap shaderMap;
    for( State::AttributeVec::iterator i = av->begin(); i != av->end(); ++i )
    {
        const osg::StateAttribute * sa = i->first;
        const VirtualProgram * effect = dynamic_cast< const VirtualProgram *>( sa );
        if( effect && ( effect->_mask & _mask ) ) {

            os << "VirtualProgram cumulate ["<< effect->getName() << "] apply" << std::endl;

               for( ShaderMap::const_iterator i = effect->_shaderMap.begin();
                                           i != effect->_shaderMap.end(); ++i )
                                                    shaderMap[ i->first ] = i->second;

        } else {
            os << "VirtualProgram cumulate ( effect from other space or not an effect ) ignore" << std::endl;

            continue; // ignore osg::Programs
        }
    }

    for( ShaderMap::const_iterator i = this->_shaderMap.begin();
                                   i != this->_shaderMap.end(); ++i )
                                        shaderMap[ i->first ] = i->second;

    os << "VirtualProgram cumulate End" << std::endl;

    if( shaderMap.size() ) {

        ShaderList sl;
        for( ShaderMap::iterator i = shaderMap.begin(); i != shaderMap.end(); ++i )
            sl.push_back( i->second );

        osg::ref_ptr< osg::Program > & program = _programMap[ sl ];

        if( !program.valid() ) {
            program = new osg::Program;
#if !MERGE_SHADERS
            for( ShaderList::iterator i = sl.begin(); i != sl.end(); ++i )
                program->addShader( i->get() );
#else
            std::string strFragment;
            std::string strVertex;
            
            for( ShaderList::iterator i = sl.begin(); i != sl.end(); ++i )
            {
                if( i->get()->getType() == osg::Shader::FRAGMENT )
                    strFragment += i->get()->getShaderSource();
                else
                    strVertex += i->get()->getShaderSource();
            }

            if( strFragment.length() > 0 ) {
                program->addShader( new osg::Shader( osg::Shader::FRAGMENT, strFragment ) );
            }

            if( strVertex.length() > 0  ) {
                program->addShader( new osg::Shader( osg::Shader::VERTEX, strVertex ) );
            }
#endif
        }

#if !MERGE_SHADERS
        assert( program->getNumShaders() == sl.size() );
#endif
        program->apply( state );
    } else {
        Program::apply( state );
    }

    os << "VirtualProgram Apply" << std::endl;

}
////////////////////////////////////////////////////////////////////////////////
}; // namespace osgExt
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to