Implemented ability to switch between different shaders with new MultipassTechnique
This commit is contained in:
parent
939aa38a2a
commit
5571c361dc
@ -1105,8 +1105,6 @@ int main( int argc, char **argv )
|
|||||||
cp->addProperty(tfp);
|
cp->addProperty(tfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
cp->addProperty(isop);
|
|
||||||
|
|
||||||
sp->addProperty(cp);
|
sp->addProperty(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,22 @@ class OSGVOLUME_EXPORT MultipassTechnique : public VolumeTechnique
|
|||||||
ModelViewMatrixMap _modelViewMatrixMap;
|
ModelViewMatrixMap _modelViewMatrixMap;
|
||||||
|
|
||||||
osg::ref_ptr<osg::StateSet> _whenMovingStateSet;
|
osg::ref_ptr<osg::StateSet> _whenMovingStateSet;
|
||||||
|
|
||||||
|
osg::StateSet* createStateSet(osg::StateSet* statesetPrototype, osg::Program* programPrototype, osg::Shader* shaderToAdd1=0, osg::Shader* shaderToAdd2=0);
|
||||||
|
|
||||||
|
enum ShaderMask
|
||||||
|
{
|
||||||
|
FRONT_SHADERS = 1,
|
||||||
|
BACK_SHADERS = 2,
|
||||||
|
STANDARD_SHADERS = 4,
|
||||||
|
LIT_SHADERS = 8,
|
||||||
|
ISO_SHADERS = 16,
|
||||||
|
MIP_SHADERS = 32,
|
||||||
|
TF_SHADERS = 64
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<int, osg::ref_ptr<osg::StateSet> > StateSetMap;
|
||||||
|
StateSetMap _stateSetMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -144,11 +144,22 @@ Program::Program() :
|
|||||||
|
|
||||||
Program::Program(const Program& rhs, const osg::CopyOp& copyop):
|
Program::Program(const Program& rhs, const osg::CopyOp& copyop):
|
||||||
osg::StateAttribute(rhs, copyop)
|
osg::StateAttribute(rhs, copyop)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((copyop.getCopyFlags()&osg::CopyOp::DEEP_COPY_STATEATTRIBUTES)!=0)
|
||||||
{
|
{
|
||||||
for( unsigned int shaderIndex=0; shaderIndex < rhs.getNumShaders(); ++shaderIndex )
|
for( unsigned int shaderIndex=0; shaderIndex < rhs.getNumShaders(); ++shaderIndex )
|
||||||
{
|
{
|
||||||
addShader( new osg::Shader( *rhs.getShader( shaderIndex ), copyop ) );
|
addShader( new osg::Shader( *rhs.getShader( shaderIndex ), copyop ) );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( unsigned int shaderIndex=0; shaderIndex < rhs.getNumShaders(); ++shaderIndex )
|
||||||
|
{
|
||||||
|
addShader( const_cast<osg::Shader*>(rhs.getShader( shaderIndex )) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const osg::Program::AttribBindingList &abl = rhs.getAttribBindingList();
|
const osg::Program::AttribBindingList &abl = rhs.getAttribBindingList();
|
||||||
for( osg::Program::AttribBindingList::const_iterator attribute = abl.begin(); attribute != abl.end(); ++attribute )
|
for( osg::Program::AttribBindingList::const_iterator attribute = abl.begin(); attribute != abl.end(); ++attribute )
|
||||||
|
@ -48,6 +48,17 @@ MultipassTechnique::~MultipassTechnique()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::StateSet* MultipassTechnique::createStateSet(osg::StateSet* statesetPrototype, osg::Program* programPrototype, osg::Shader* shaderToAdd1, osg::Shader* shaderToAdd2)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::StateSet> stateset = osg::clone(statesetPrototype, osg::CopyOp::SHALLOW_COPY);
|
||||||
|
osg::ref_ptr<osg::Program> program = osg::clone(programPrototype, osg::CopyOp::SHALLOW_COPY);
|
||||||
|
stateset->setAttribute(program.get());
|
||||||
|
if (shaderToAdd1) program->addShader(shaderToAdd1);
|
||||||
|
if (shaderToAdd2) program->addShader(shaderToAdd2);
|
||||||
|
|
||||||
|
return stateset.release();
|
||||||
|
}
|
||||||
|
|
||||||
void MultipassTechnique::init()
|
void MultipassTechnique::init()
|
||||||
{
|
{
|
||||||
OSG_INFO<<"MultipassTechnique::init()"<<std::endl;
|
OSG_INFO<<"MultipassTechnique::init()"<<std::endl;
|
||||||
@ -72,7 +83,7 @@ void MultipassTechnique::init()
|
|||||||
|
|
||||||
OSG_NOTICE<<"MultipassTechnique::init() Need to set up"<<std::endl;
|
OSG_NOTICE<<"MultipassTechnique::init() Need to set up"<<std::endl;
|
||||||
|
|
||||||
CollectPropertiesVisitor cpv;
|
CollectPropertiesVisitor cpv(false);
|
||||||
if (_volumeTile->getLayer()->getProperty())
|
if (_volumeTile->getLayer()->getProperty())
|
||||||
{
|
{
|
||||||
_volumeTile->getLayer()->getProperty()->accept(cpv);
|
_volumeTile->getLayer()->getProperty()->accept(cpv);
|
||||||
@ -142,6 +153,7 @@ void MultipassTechnique::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_transform = new osg::MatrixTransform;
|
_transform = new osg::MatrixTransform;
|
||||||
|
_transform->addChild(geode.get());
|
||||||
|
|
||||||
// handle locators
|
// handle locators
|
||||||
Locator* masterLocator = _volumeTile->getLocator();
|
Locator* masterLocator = _volumeTile->getLocator();
|
||||||
@ -215,7 +227,6 @@ void MultipassTechnique::init()
|
|||||||
tf = dynamic_cast<osg::TransferFunction1D*>(cpv._tfProperty->getTransferFunction());
|
tf = dynamic_cast<osg::TransferFunction1D*>(cpv._tfProperty->getTransferFunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
|
||||||
osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen;
|
osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen;
|
||||||
texgen->setMode(osg::TexGen::OBJECT_LINEAR);
|
texgen->setMode(osg::TexGen::OBJECT_LINEAR);
|
||||||
texgen->setPlanesFromMatrix( geometryMatrix * osg::Matrix::inverse(imageMatrix));
|
texgen->setPlanesFromMatrix( geometryMatrix * osg::Matrix::inverse(imageMatrix));
|
||||||
@ -231,7 +242,6 @@ void MultipassTechnique::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
stateset->setTextureAttributeAndModes(texgenTextureUnit, texgen.get(), osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(texgenTextureUnit, texgen.get(), osg::StateAttribute::ON);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -317,6 +327,11 @@ void MultipassTechnique::init()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// creates CullFace attributes to apply to front/back StateSet configurations.
|
||||||
|
osg::ref_ptr<osg::CullFace> front_CullFace = new osg::CullFace(osg::CullFace::BACK);
|
||||||
|
osg::ref_ptr<osg::CullFace> back_CullFace = new osg::CullFace(osg::CullFace::FRONT);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Shader> computeRayColorShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_compute_ray_color.frag");
|
osg::ref_ptr<osg::Shader> computeRayColorShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_compute_ray_color.frag");
|
||||||
#if 0
|
#if 0
|
||||||
@ -327,95 +342,222 @@ void MultipassTechnique::init()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// set up the renderin of the front faces
|
osg::ref_ptr<osg::Shader> main_vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_multipass.vert");
|
||||||
{
|
|
||||||
osg::ref_ptr<osg::Group> front_face_group = new osg::Group;
|
|
||||||
front_face_group->addChild(geode.get());
|
|
||||||
_transform->addChild(front_face_group.get());
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::StateSet> front_face_stateset = front_face_group->getOrCreateStateSet();
|
|
||||||
front_face_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON);
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Program> program = new osg::Program;
|
|
||||||
front_face_stateset->setAttribute(program);
|
|
||||||
|
|
||||||
// get vertex shaders from source
|
|
||||||
osg::ref_ptr<osg::Shader> vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_multipass_front.vert");
|
|
||||||
if (vertexShader.valid())
|
|
||||||
{
|
|
||||||
program->addShader(vertexShader.get());
|
|
||||||
}
|
|
||||||
#if 0
|
#if 0
|
||||||
else
|
if (!main_vertexShader)
|
||||||
{
|
{
|
||||||
#include "Shaders/volume_color_depth_vert.cpp"
|
#include "Shaders/volume_multipass_vert.cpp"
|
||||||
program->addShader(new osg::Shader(osg::Shader::VERTEX, volume_color_depth_vert));
|
main_vertexShader = new osg::Shader(osg::Shader::VERTEX, volume_multipass_vert));
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// get fragment shaders from source
|
|
||||||
osg::ref_ptr<osg::Shader> fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass_front.frag");
|
|
||||||
if (fragmentShader.valid())
|
|
||||||
{
|
|
||||||
program->addShader(fragmentShader.get());
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#include "Shaders/volume_color_depth_frag.cpp"
|
|
||||||
program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_color_depth_frag));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (computeRayColorShader.valid())
|
osg::ref_ptr<osg::Shader> front_main_fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass_front.frag");
|
||||||
{
|
|
||||||
program->addShader(computeRayColorShader.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// set up the rendering of the back faces
|
|
||||||
{
|
|
||||||
osg::ref_ptr<osg::Group> back_face_group = new osg::Group;
|
|
||||||
back_face_group->addChild(geode.get());
|
|
||||||
_transform->addChild(back_face_group.get());
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::StateSet> back_face_stateset = back_face_group->getOrCreateStateSet();
|
|
||||||
back_face_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::FRONT), osg::StateAttribute::ON);
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Program> program = new osg::Program;
|
|
||||||
back_face_stateset->setAttribute(program);
|
|
||||||
|
|
||||||
// get vertex shaders from source
|
|
||||||
osg::ref_ptr<osg::Shader> vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_multipass_back.vert");
|
|
||||||
if (vertexShader.valid())
|
|
||||||
{
|
|
||||||
program->addShader(vertexShader.get());
|
|
||||||
}
|
|
||||||
#if 0
|
#if 0
|
||||||
else
|
if (!front_main_fragmentShader)
|
||||||
{
|
{
|
||||||
#include "Shaders/volume_color_depth_vert.cpp"
|
#include "Shaders/volume_multipass_front_frag.cpp"
|
||||||
program->addShader(new osg::Shader(osg::Shader::VERTEX, volume_color_depth_vert));
|
front_main_fragmentShader = new osg::Shader(osg::Shader::VERTEX, volume_multipass_front_frag));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// get fragment shaders from source
|
|
||||||
osg::ref_ptr<osg::Shader> fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass_back.frag");
|
|
||||||
if (fragmentShader.valid())
|
osg::ref_ptr<osg::Shader> back_main_fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_multipass_back.frag");
|
||||||
{
|
|
||||||
program->addShader(fragmentShader.get());
|
|
||||||
}
|
|
||||||
#if 0
|
#if 0
|
||||||
else
|
if (!back_main_fragmentShader)
|
||||||
{
|
{
|
||||||
#include "Shaders/volume_color_depth_frag.cpp"
|
#include "Shaders/volume_multipass_back_frag.cpp"
|
||||||
program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_color_depth_frag));
|
back_main_fragmentShader = new osg::Shader(osg::Shader::VERTEX, volume_multipass_back_frag));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (computeRayColorShader.valid())
|
|
||||||
|
// clear any previous settings
|
||||||
|
_stateSetMap.clear();
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::StateSet> front_stateset_prototype = new osg::StateSet;
|
||||||
|
osg::ref_ptr<osg::Program> front_program_prototype = new osg::Program;
|
||||||
{
|
{
|
||||||
program->addShader(computeRayColorShader.get());
|
front_stateset_prototype->setAttributeAndModes(front_CullFace.get(), osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
front_program_prototype->addShader(main_vertexShader.get());
|
||||||
|
front_program_prototype->addShader(front_main_fragmentShader.get());
|
||||||
|
front_program_prototype->addShader(computeRayColorShader.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::StateSet> back_stateset_prototype = new osg::StateSet;
|
||||||
|
osg::ref_ptr<osg::Program> back_program_prototype = new osg::Program;
|
||||||
|
{
|
||||||
|
back_stateset_prototype->setAttributeAndModes(back_CullFace.get(), osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
back_program_prototype->addShader(main_vertexShader.get());
|
||||||
|
back_program_prototype->addShader(back_main_fragmentShader.get());
|
||||||
|
back_program_prototype->addShader(computeRayColorShader.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// STANDARD_SHADERS
|
||||||
|
{
|
||||||
|
// STANDARD_SHADERS without TransferFunction
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_standard.frag");
|
||||||
|
#if 0
|
||||||
|
if (!accumulateSamplesShader)
|
||||||
|
{
|
||||||
|
#include "Shaders/volume_accumulateSamples_standard_frag.cpp";
|
||||||
|
accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_frag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// front
|
||||||
|
_stateSetMap[STANDARD_SHADERS|FRONT_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
|
||||||
|
// back
|
||||||
|
_stateSetMap[STANDARD_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// STANDARD_SHADERS with TransferFunction
|
||||||
|
if (tf)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_standard_tf.frag");
|
||||||
|
#if 0
|
||||||
|
if (!accumulateSamplesShader)
|
||||||
|
{
|
||||||
|
#include "Shaders/volume_accumulateSamples_standard_tf_frag.cpp";
|
||||||
|
accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_tf_frag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// front
|
||||||
|
_stateSetMap[STANDARD_SHADERS|FRONT_SHADERS|TF_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
|
||||||
|
// back
|
||||||
|
_stateSetMap[STANDARD_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ISO_SHADERS
|
||||||
|
if (cpv._isoProperty.valid())
|
||||||
|
{
|
||||||
|
// ISO_SHADERS without TransferFunction
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_iso.frag");
|
||||||
|
#if 0
|
||||||
|
if (!accumulateSamplesShader)
|
||||||
|
{
|
||||||
|
#include "Shaders/volume_accumulateSamples_iso_frag.cpp";
|
||||||
|
accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_iso_frag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// front
|
||||||
|
_stateSetMap[ISO_SHADERS|FRONT_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
|
||||||
|
// back
|
||||||
|
_stateSetMap[ISO_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ISO_SHADERS with TransferFunction
|
||||||
|
if (tf)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_iso_tf.frag");
|
||||||
|
#if 0
|
||||||
|
if (!accumulateSamplesShader)
|
||||||
|
{
|
||||||
|
#include "Shaders/volume_accumulateSamples_standard_iso_tf_frag.cpp";
|
||||||
|
accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_iso_tf_frag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// front
|
||||||
|
_stateSetMap[ISO_SHADERS|FRONT_SHADERS|TF_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
|
||||||
|
// back
|
||||||
|
_stateSetMap[ISO_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MIP_SHADERS
|
||||||
|
if (cpv._mipProperty.valid())
|
||||||
|
{
|
||||||
|
// MIP_SHADERS without TransferFunction
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_mip.frag");
|
||||||
|
#if 0
|
||||||
|
if (!accumulateSamplesShader)
|
||||||
|
{
|
||||||
|
#include "Shaders/volume_accumulateSamples_mip_frag.cpp";
|
||||||
|
accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_mip_frag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// front
|
||||||
|
_stateSetMap[MIP_SHADERS|FRONT_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
|
||||||
|
// back
|
||||||
|
_stateSetMap[MIP_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// MIP_SHADERS with TransferFunction
|
||||||
|
if (tf)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_mip_tf.frag");
|
||||||
|
#if 0
|
||||||
|
if (!accumulateSamplesShader)
|
||||||
|
{
|
||||||
|
#include "Shaders/volume_accumulateSamples_standard_mip_tf_frag.cpp";
|
||||||
|
accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_mip_tf_frag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// front
|
||||||
|
_stateSetMap[MIP_SHADERS|FRONT_SHADERS|TF_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
|
||||||
|
// back
|
||||||
|
_stateSetMap[MIP_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LIT_SHADERS
|
||||||
|
if (cpv._lightingProperty.valid())
|
||||||
|
{
|
||||||
|
// LIT_SHADERS without TransferFunction
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_lit.frag");
|
||||||
|
#if 0
|
||||||
|
if (!accumulateSamplesShader)
|
||||||
|
{
|
||||||
|
#include "Shaders/volume_accumulateSamples_lit_frag.cpp";
|
||||||
|
accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_lit_frag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// front
|
||||||
|
_stateSetMap[LIT_SHADERS|FRONT_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
|
||||||
|
// back
|
||||||
|
_stateSetMap[LIT_SHADERS|BACK_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// MIP_SHADERS with TransferFunction
|
||||||
|
if (tf)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Shader> accumulateSamplesShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_accumulateSamples_lit_tf.frag");
|
||||||
|
#if 0
|
||||||
|
if (!accumulateSamplesShader)
|
||||||
|
{
|
||||||
|
#include "Shaders/volume_accumulateSamples_standard_lit_tf_frag.cpp";
|
||||||
|
accumulateSamplesShader = new osg::Shader(osg::Shader::FRAGMENT, volume_accumulateSamples_standard_lit_tf_frag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// front
|
||||||
|
_stateSetMap[LIT_SHADERS|FRONT_SHADERS|TF_SHADERS] = createStateSet(front_stateset_prototype.get(), front_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
|
||||||
|
// back
|
||||||
|
_stateSetMap[LIT_SHADERS|BACK_SHADERS|TF_SHADERS] = createStateSet(back_stateset_prototype.get(), back_program_prototype.get(), accumulateSamplesShader.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -441,17 +583,73 @@ void MultipassTechnique::cull(osgUtil::CullVisitor* cv)
|
|||||||
|
|
||||||
if (postTraversal)
|
if (postTraversal)
|
||||||
{
|
{
|
||||||
if (_whenMovingStateSet.valid() && isMoving(cv))
|
|
||||||
|
int shaderMask = 0;
|
||||||
|
if (_volumeTile->getLayer()->getProperty())
|
||||||
{
|
{
|
||||||
OSG_NOTICE<<"Using MovingStateSet"<<std::endl;
|
CollectPropertiesVisitor cpv;
|
||||||
cv->pushStateSet(_whenMovingStateSet.get());
|
_volumeTile->getLayer()->getProperty()->accept(cpv);
|
||||||
_transform->accept(*cv);
|
|
||||||
cv->popStateSet();
|
if (cpv._tfProperty.valid())
|
||||||
|
{
|
||||||
|
shaderMask |= TF_SHADERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpv._isoProperty.valid())
|
||||||
|
{
|
||||||
|
shaderMask |= ISO_SHADERS;
|
||||||
|
}
|
||||||
|
else if (cpv._mipProperty.valid())
|
||||||
|
{
|
||||||
|
shaderMask |= MIP_SHADERS;
|
||||||
|
}
|
||||||
|
else if (cpv._lightingProperty.valid())
|
||||||
|
{
|
||||||
|
shaderMask |= LIT_SHADERS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OSG_NOTICE<<"NOT using MovingStateSet"<<std::endl;
|
shaderMask |= STANDARD_SHADERS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int shaderMaskFront = shaderMask | FRONT_SHADERS;
|
||||||
|
int shaderMaskBack = shaderMask | BACK_SHADERS;
|
||||||
|
|
||||||
|
OSG_NOTICE<<"shaderMaskFront "<<shaderMaskFront<<std::endl;
|
||||||
|
OSG_NOTICE<<"shaderMaskBack "<<shaderMaskBack<<std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::StateSet> front_stateset = _stateSetMap[shaderMaskFront];
|
||||||
|
osg::ref_ptr<osg::StateSet> back_stateset = _stateSetMap[shaderMaskBack];
|
||||||
|
osg::ref_ptr<osg::StateSet> moving_stateset = (_whenMovingStateSet.valid() && isMoving(cv)) ? _whenMovingStateSet : 0;
|
||||||
|
|
||||||
|
if (moving_stateset.valid())
|
||||||
|
{
|
||||||
|
// OSG_NOTICE<<"Using MovingStateSet"<<std::endl;
|
||||||
|
cv->pushStateSet(moving_stateset.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (front_stateset.valid())
|
||||||
|
{
|
||||||
|
OSG_NOTICE<<"Have front stateset"<<std::endl;
|
||||||
|
cv->pushStateSet(front_stateset.get());
|
||||||
_transform->accept(*cv);
|
_transform->accept(*cv);
|
||||||
|
cv->popStateSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (back_stateset.valid())
|
||||||
|
{
|
||||||
|
OSG_NOTICE<<"Have back stateset"<<std::endl;
|
||||||
|
cv->pushStateSet(back_stateset.get());
|
||||||
|
_transform->accept(*cv);
|
||||||
|
cv->popStateSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moving_stateset.valid())
|
||||||
|
{
|
||||||
|
// OSG_NOTICE<<"Using MovingStateSet"<<std::endl;
|
||||||
|
cv->popStateSet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <osgVolume/Property>
|
#include <osgVolume/Property>
|
||||||
#include <osgVolume/VolumeTile>
|
#include <osgVolume/VolumeTile>
|
||||||
|
#include <osgVolume/RayTracedTechnique>
|
||||||
|
|
||||||
using namespace osgVolume;
|
using namespace osgVolume;
|
||||||
|
|
||||||
@ -400,11 +401,14 @@ bool PropertyAdjustmentCallback::handle(const osgGA::GUIEventAdapter& ea,osgGA::
|
|||||||
CycleSwitchVisitor csv( (ea.getKey()==_cyleForwardKey) ? 1 : -1);
|
CycleSwitchVisitor csv( (ea.getKey()==_cyleForwardKey) ? 1 : -1);
|
||||||
property->accept(csv);
|
property->accept(csv);
|
||||||
if (csv._switchModified)
|
if (csv._switchModified)
|
||||||
|
{
|
||||||
|
if (dynamic_cast<osgVolume::RayTracedTechnique*>(tile->getVolumeTechnique()))
|
||||||
{
|
{
|
||||||
tile->setDirty(true);
|
tile->setDirty(true);
|
||||||
tile->init();
|
tile->init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (ea.getKey()==_transparencyKey) _updateTransparency = passOnUpdates = true;
|
else if (ea.getKey()==_transparencyKey) _updateTransparency = passOnUpdates = true;
|
||||||
else if (ea.getKey()==_alphaFuncKey) _updateAlphaCutOff = passOnUpdates = true;
|
else if (ea.getKey()==_alphaFuncKey) _updateAlphaCutOff = passOnUpdates = true;
|
||||||
else if (ea.getKey()==_sampleDensityKey) _updateSampleDensity = passOnUpdates = true;
|
else if (ea.getKey()==_sampleDensityKey) _updateSampleDensity = passOnUpdates = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user