From 2efce3965a9aa8c987e93cab8269fb71f0336a7d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 13 Jan 2009 17:51:45 +0000 Subject: [PATCH] Integrated state setup code from osgvolume.cpp example into ShaderTechnique path. --- src/osgVolume/ShaderTechnique.cpp | 295 +++++++++++++++++++++++++++++- 1 file changed, 292 insertions(+), 3 deletions(-) diff --git a/src/osgVolume/ShaderTechnique.cpp b/src/osgVolume/ShaderTechnique.cpp index 0c7a7ede9..ca5710ebf 100644 --- a/src/osgVolume/ShaderTechnique.cpp +++ b/src/osgVolume/ShaderTechnique.cpp @@ -17,6 +17,15 @@ #include #include +#include +#include +#include +#include +#include +#include + +#include + using namespace osgVolume; ShaderTechnique::ShaderTechnique() @@ -32,24 +41,44 @@ ShaderTechnique::~ShaderTechnique() { } +enum ShadingModel +{ + Standard, + Light, + Isosurface, + MaximumIntensityProjection +}; + void ShaderTechnique::init() { osg::notify(osg::NOTICE)<<"ShaderTechnique::init()"<getLocator(); for(unsigned int i = 0; - i < _volumeTile->getNumLayers() && !masterLocator; + i < _volumeTile->getNumLayers(); ++i) { - if (_volumeTile->getLayer(i)) + if (_volumeTile->getLayer(i) && !masterLocator) { masterLocator = _volumeTile->getLayer(i)->getLocator(); osg::notify(osg::NOTICE)<<"assigning locator = "<getLayer(i)->getImage()) + { + osg::notify(osg::NOTICE)<<"assigning image = "<getLayer(i)->getImage(); + tf = dynamic_cast(_volumeTile->getLayer(i)->getTransferFunction()); + } } osg::Matrix matrix; @@ -59,7 +88,267 @@ void ShaderTechnique::init() } osg::notify(osg::NOTICE)<<"Matrix = "<getOrCreateStateSet(); + + stateset->setMode(GL_ALPHA_TEST,osg::StateAttribute::ON); + + osg::Program* program = new osg::Program; + stateset->setAttribute(program); + + // get shaders from source + + osg::Shader* vertexShader = osgDB::readShaderFile(osg::Shader::VERTEX, "volume.vert"); + if (vertexShader) + { + program->addShader(vertexShader); + } + else + { + #include "Shaders/volume_vert.cpp" + program->addShader(new osg::Shader(osg::Shader::VERTEX, volume_vert)); + } + + if (!(normalmap_3d && tf)) + { + // set up the 3d texture itself, + // note, well set the filtering up so that mip mapping is disabled, + // gluBuild3DMipsmaps doesn't do a very good job of handled the + // imbalanced dimensions of the 256x256x4 texture. + osg::Texture3D* texture3D = new osg::Texture3D; + texture3D->setResizeNonPowerOfTwoHint(false); + texture3D->setFilter(osg::Texture3D::MIN_FILTER,minFilter); + texture3D->setFilter(osg::Texture3D::MAG_FILTER, magFilter); + texture3D->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::CLAMP_TO_EDGE); + texture3D->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_EDGE); + texture3D->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_EDGE); + if (image_3d->getPixelFormat()==GL_ALPHA || + image_3d->getPixelFormat()==GL_LUMINANCE) + { + texture3D->setInternalFormatMode(osg::Texture3D::USE_USER_DEFINED_FORMAT); + texture3D->setInternalFormat(GL_INTENSITY); + } + else + { + texture3D->setInternalFormatMode(internalFormatMode); + } + texture3D->setImage(image_3d); + + stateset->setTextureAttributeAndModes(0,texture3D,osg::StateAttribute::ON); + + osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0); + stateset->addUniform(baseTextureSampler); + } + + + if (shadingModel==MaximumIntensityProjection) + { + if (tf) + { + osg::Texture1D* texture1D = new osg::Texture1D; + texture1D->setImage(tf->getImage()); + stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON); + + osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume_tf_mip.frag"); + if (fragmentShader) + { + program->addShader(fragmentShader); + } + else + { + #include "Shaders/volume_tf_mip_frag.cpp" + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_tf_mip_frag)); + } + + osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",1); + stateset->addUniform(tfTextureSampler); + + } + else + { + osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume_mip.frag"); + if (fragmentShader) + { + program->addShader(fragmentShader); + } + else + { + #include "Shaders/volume_mip_frag.cpp" + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_mip_frag)); + } + } + } + else if (shadingModel==Isosurface) + { + + if (tf) + { + osg::Texture1D* texture1D = new osg::Texture1D; + texture1D->setImage(tf->getImage()); + texture1D->setResizeNonPowerOfTwoHint(false); + texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); + texture1D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); + texture1D->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE); + stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON); + + osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",1); + stateset->addUniform(tfTextureSampler); + + osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume_tf_iso.frag"); + if (fragmentShader) + { + program->addShader(fragmentShader); + } + else + { + #include "Shaders/volume_tf_iso_frag.cpp" + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_tf_iso_frag)); + } + } + else + { + osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume_iso.frag"); + if (fragmentShader) + { + program->addShader(fragmentShader); + } + else + { + #include "Shaders/volume_iso_frag.cpp" + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_iso_frag)); + } + } + } + else if (normalmap_3d) + { + osg::notify(osg::NOTICE)<<"Setting up normalmapping shader"<addUniform(normalMapSampler); + + osg::Texture3D* normalMap = new osg::Texture3D; + normalMap->setImage(normalmap_3d); + normalMap->setResizeNonPowerOfTwoHint(false); + normalMap->setInternalFormatMode(internalFormatMode); + normalMap->setFilter(osg::Texture3D::MIN_FILTER, osg::Texture::LINEAR); + normalMap->setFilter(osg::Texture3D::MAG_FILTER, osg::Texture::LINEAR); + normalMap->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::CLAMP_TO_EDGE); + normalMap->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_EDGE); + normalMap->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_EDGE); + + stateset->setTextureAttributeAndModes(1,normalMap,osg::StateAttribute::ON); + + if (tf) + { + osg::Texture1D* texture1D = new osg::Texture1D; + texture1D->setImage(tf->getImage()); + texture1D->setResizeNonPowerOfTwoHint(false); + texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); + texture1D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); + texture1D->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE); + stateset->setTextureAttributeAndModes(0,texture1D,osg::StateAttribute::ON); + + osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume-tf-n.frag"); + if (fragmentShader) + { + program->addShader(fragmentShader); + } + else + { + #include "Shaders/volume_tf_n_frag.cpp" + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_tf_n_frag)); + } + + osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",0); + stateset->addUniform(tfTextureSampler); + } + else + { + osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume-n.frag"); + if (fragmentShader) + { + program->addShader(fragmentShader); + } + else + { + #include "Shaders/volume_n_frag.cpp" + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_n_frag)); + } + } + } + else if (tf) + { + osg::Texture1D* texture1D = new osg::Texture1D; + texture1D->setImage(tf->getImage()); + texture1D->setResizeNonPowerOfTwoHint(false); + texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); + texture1D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); + texture1D->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE); + stateset->setTextureAttributeAndModes(1,texture1D,osg::StateAttribute::ON); + + osg::Uniform* tfTextureSampler = new osg::Uniform("tfTexture",1); + stateset->addUniform(tfTextureSampler); + + osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume-tf.frag"); + if (fragmentShader) + { + program->addShader(fragmentShader); + } + else + { + #include "Shaders/volume_tf_frag.cpp" + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_tf_frag)); + } + + } + else + { + + osg::Shader* fragmentShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "volume.frag"); + if (fragmentShader) + { + program->addShader(fragmentShader); + } + else + { + #include "Shaders/volume_frag.cpp" + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_frag)); + } + } + + osg::Uniform* sampleDensity = new osg::Uniform("sampleDensity", 0.005f); + stateset->addUniform(sampleDensity); + + osg::Uniform* transpancy = new osg::Uniform("transparency",0.5f); + stateset->addUniform(transpancy); + + osg::Uniform* alphaCutOff = new osg::Uniform("alphaCutOff",alphaFuncValue); + stateset->addUniform(alphaCutOff); + + stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON); + + osg::TexGen* texgen = new osg::TexGen; + texgen->setMode(osg::TexGen::OBJECT_LINEAR); + texgen->setPlane(osg::TexGen::S, osg::Plane(1.0f/xSize,0.0f,0.0f,0.0f)); + texgen->setPlane(osg::TexGen::T, osg::Plane(0.0f,1.0f/ySize,0.0f,0.0f)); + texgen->setPlane(osg::TexGen::R, osg::Plane(0.0f,0.0f,1.0f/zSize,0.0f)); + texgen->setPlane(osg::TexGen::Q, osg::Plane(0.0f,0.0f,0.0f,1.0f)); + + stateset->setTextureAttributeAndModes(0, texgen, osg::StateAttribute::ON); + + } + { osg::Geometry* geom = new osg::Geometry;