diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index 81c2bdf68..090722677 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -63,6 +63,8 @@ #include #include #include +#include +#include typedef std::vector< osg::ref_ptr > ImageList; @@ -2291,9 +2293,29 @@ int main( int argc, char **argv ) osg::ref_ptr volume = new osgVolume::Volume; osg::ref_ptr tile = new osgVolume::VolumeTile; - osg::ref_ptr layer = new osgVolume::ImageLayer(image_3d); - tile->addLayer(layer.get()); volume->addChild(tile); + + osg::ref_ptr layer = new osgVolume::ImageLayer(image_3d); + layer->setTransferFunction(transferFunction.get()); + + if (matrix) + { + osgVolume::Locator* locator = new osgVolume::Locator(*matrix); + layer->setLocator(locator); + tile->setLocator(locator); + } + + tile->addLayer(layer.get()); + + if (useShader) + { + tile->setVolumeTechnique(new osgVolume::ShaderTechnique); + } + else + { + tile->setVolumeTechnique(new osgVolume::FixedFunctionTechnique); + } + rootNode = volume.get(); diff --git a/include/osgVolume/FixedFunctionTechnique b/include/osgVolume/FixedFunctionTechnique new file mode 100644 index 000000000..450eda1d5 --- /dev/null +++ b/include/osgVolume/FixedFunctionTechnique @@ -0,0 +1,51 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGVOLUME_FIXEDFUNCTIONTECHNIQUE +#define OSGVOLUME_FIXEDFUNCTIONTECHNIQUE 1 + +#include + +namespace osgVolume { + +class OSGVOLUME_EXPORT FixedFunctionTechnique : public VolumeTechnique +{ + public: + + FixedFunctionTechnique(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + FixedFunctionTechnique(const FixedFunctionTechnique&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Object(osgVolume, FixedFunctionTechnique); + + virtual void init(); + + virtual void update(osgUtil::UpdateVisitor* nv); + + virtual void cull(osgUtil::CullVisitor* nv); + + /** Clean scene graph from any terrain technique specific nodes.*/ + virtual void cleanSceneGraph(); + + /** Traverse the terrain subgraph.*/ + virtual void traverse(osg::NodeVisitor& nv); + + protected: + + virtual ~FixedFunctionTechnique(); +}; + +} + +#endif diff --git a/include/osgVolume/ShaderTechnique b/include/osgVolume/ShaderTechnique new file mode 100644 index 000000000..4c54410d8 --- /dev/null +++ b/include/osgVolume/ShaderTechnique @@ -0,0 +1,52 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGVOLUME_SHADERTECHNIQUE +#define OSGVOLUME_SHADERTECHNIQUE 1 + +#include + +namespace osgVolume { + +class OSGVOLUME_EXPORT ShaderTechnique : public VolumeTechnique +{ + public: + + ShaderTechnique(); + + ShaderTechnique(const ShaderTechnique&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Object(osgVolume, ShaderTechnique); + + virtual void init(); + + virtual void update(osgUtil::UpdateVisitor* nv); + + virtual void cull(osgUtil::CullVisitor* nv); + + /** Clean scene graph from any terrain technique specific nodes.*/ + virtual void cleanSceneGraph(); + + /** Traverse the terrain subgraph.*/ + virtual void traverse(osg::NodeVisitor& nv); + + protected: + + virtual ~ShaderTechnique(); + + osg::ref_ptr _geode; +}; + +} + +#endif diff --git a/include/osgVolume/VolumeTile b/include/osgVolume/VolumeTile index 9d5196d82..064640a0d 100644 --- a/include/osgVolume/VolumeTile +++ b/include/osgVolume/VolumeTile @@ -122,7 +122,7 @@ class OSGVOLUME_EXPORT VolumeTile : public osg::Group void addLayer(Layer* layer) { if (layer) _layers.push_back(layer); } unsigned int getNumLayers() { return _layers.size(); } - + /** Set the VolumeTechnique*/ void setVolumeTechnique(VolumeTechnique* VolumeTechnique); diff --git a/src/osgPlugins/dicom/ReaderWriterDICOM.cpp b/src/osgPlugins/dicom/ReaderWriterDICOM.cpp index 79f7edfbb..905780825 100644 --- a/src/osgPlugins/dicom/ReaderWriterDICOM.cpp +++ b/src/osgPlugins/dicom/ReaderWriterDICOM.cpp @@ -136,12 +136,19 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter // scale up to provide scale of complete tile osg::Vec3d scale(osg::Vec3(result.getImage()->s(),result.getImage()->t(), result.getImage()->r())); matrix->postMultScale(scale); + + osgVolume::Locator* locator = new osgVolume::Locator(*matrix); - tile->setLocator(new osgVolume::Locator(*matrix)); + tile->setLocator(locator); + layer->setLocator(locator); - result.getImage()->setUserData(0); + // result.getImage()->setUserData(0); - notice()<<"Locator "<<*matrix<addChild(tile.get()); diff --git a/src/osgVolume/CMakeLists.txt b/src/osgVolume/CMakeLists.txt index d7be29dc6..bb8e9816d 100644 --- a/src/osgVolume/CMakeLists.txt +++ b/src/osgVolume/CMakeLists.txt @@ -9,10 +9,12 @@ SET(LIB_NAME osgVolume) SET(HEADER_PATH ${OpenSceneGraph_SOURCE_DIR}/include/${LIB_NAME}) SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/Export + ${HEADER_PATH}/FixedFunctionTechnique + ${HEADER_PATH}/Layer + ${HEADER_PATH}/Locator + ${HEADER_PATH}/ShaderTechnique ${HEADER_PATH}/Version ${HEADER_PATH}/Volume - ${HEADER_PATH}/Locator - ${HEADER_PATH}/Layer ${HEADER_PATH}/VolumeTechnique ${HEADER_PATH}/VolumeTile ) @@ -21,11 +23,13 @@ SET(LIB_PUBLIC_HEADERS ADD_LIBRARY(${LIB_NAME} ${OPENSCENEGRAPH_USER_DEFINED_DYNAMIC_OR_STATIC} ${LIB_PUBLIC_HEADERS} + FixedFunctionTechnique.cpp + Layer.cpp + Locator.cpp + ShaderTechnique.cpp Version.cpp Volume.cpp VolumeTechnique.cpp - Layer.cpp - Locator.cpp VolumeTile.cpp ) diff --git a/src/osgVolume/FixedFunctionTechnique.cpp b/src/osgVolume/FixedFunctionTechnique.cpp new file mode 100644 index 000000000..390278a48 --- /dev/null +++ b/src/osgVolume/FixedFunctionTechnique.cpp @@ -0,0 +1,55 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include + +using namespace osgVolume; + +FixedFunctionTechnique::FixedFunctionTechnique() +{ +} + +FixedFunctionTechnique::FixedFunctionTechnique(const FixedFunctionTechnique& fft,const osg::CopyOp& copyop): + VolumeTechnique(fft,copyop) +{ +} + +FixedFunctionTechnique::~FixedFunctionTechnique() +{ +} + +void FixedFunctionTechnique::init() +{ + osg::notify(osg::NOTICE)<<"FixedFunctionTechnique::init()"< +#include +#include + using namespace osgVolume; Layer::Layer(): @@ -39,6 +42,9 @@ osg::BoundingSphere Layer::computeBound() const osg::Vec3d left, right; getLocator()->computeLocalBounds(left, right); + + osg::notify(osg::NOTICE)<<"left = "<getLocator(); + for(unsigned int i = 0; + i < _volumeTile->getNumLayers() && !masterLocator; + ++i) + { + if (_volumeTile->getLayer(i)) + { + masterLocator = _volumeTile->getLayer(i)->getLocator(); + osg::notify(osg::NOTICE)<<"assigning locator = "<getTransform(); + } + + osg::notify(osg::NOTICE)<<"Matrix = "<setVertexArray(coords); + + osg::Vec4Array* colours = new osg::Vec4Array(1); + (*colours)[0].set(1.0f,1.0f,1.0,1.0f); + geom->setColorArray(colours); + geom->setColorBinding(osg::Geometry::BIND_OVERALL); + + osg::DrawElementsUShort* drawElements = new osg::DrawElementsUShort(GL_QUADS); + // bottom + drawElements->push_back(0); + drawElements->push_back(1); + drawElements->push_back(2); + drawElements->push_back(3); + + // bottom + drawElements->push_back(3); + drawElements->push_back(2); + drawElements->push_back(6); + drawElements->push_back(7); + + // left + drawElements->push_back(0); + drawElements->push_back(3); + drawElements->push_back(7); + drawElements->push_back(4); + + // right + drawElements->push_back(5); + drawElements->push_back(6); + drawElements->push_back(2); + drawElements->push_back(1); + + // front + drawElements->push_back(1); + drawElements->push_back(0); + drawElements->push_back(4); + drawElements->push_back(5); + + // top + drawElements->push_back(7); + drawElements->push_back(6); + drawElements->push_back(5); + drawElements->push_back(4); + + geom->addPrimitiveSet(drawElements); + + _geode->addDrawable(geom); + + } + +} + +void ShaderTechnique::update(osgUtil::UpdateVisitor* uv) +{ +// osg::notify(osg::NOTICE)<<"ShaderTechnique:update(osgUtil::UpdateVisitor* nv):"<accept(*cv); + } +} + +void ShaderTechnique::cleanSceneGraph() +{ + osg::notify(osg::NOTICE)<<"ShaderTechnique::cleanSceneGraph()"<getDirty()) _volumeTile->init(); + + osgUtil::UpdateVisitor* uv = dynamic_cast(&nv); + if (uv) + { + update(uv); + return; + } + + } + else if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR) + { + osgUtil::CullVisitor* cv = dynamic_cast(&nv); + if (cv) + { + cull(cv); + return; + } + } + + + if (_volumeTile->getDirty()) + { + osg::notify(osg::INFO)<<"******* Doing init ***********"<init(); + } +} + diff --git a/src/osgVolume/Shaders/volume_frag.cpp b/src/osgVolume/Shaders/volume_frag.cpp new file mode 100644 index 000000000..ec4c98d82 --- /dev/null +++ b/src/osgVolume/Shaders/volume_frag.cpp @@ -0,0 +1,99 @@ +char volume_frag[] = "uniform sampler3D baseTexture;\n" + "uniform float sampleDensity;\n" + "uniform float transparency;\n" + "uniform float alphaCutOff;\n" + "\n" + "varying vec4 cameraPos;\n" + "varying vec4 vertexPos;\n" + "varying mat4 texgen;\n" + "\n" + "void main(void)\n" + "{ \n" + " vec3 t0 = (texgen * vertexPos).xyz;\n" + " vec3 te = (texgen * cameraPos).xyz;\n" + "\n" + " if (te.x>=0.0 && te.x<=1.0 &&\n" + " te.y>=0.0 && te.y<=1.0 &&\n" + " te.z>=0.0 && te.z<=1.0)\n" + " {\n" + " // do nothing... te inside volume\n" + " }\n" + " else\n" + " {\n" + " if (te.x<0.0)\n" + " {\n" + " float r = -te.x / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.x>1.0)\n" + " {\n" + " float r = (1.0-te.x) / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y<0.0)\n" + " {\n" + " float r = -te.y / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y>1.0)\n" + " {\n" + " float r = (1.0-te.y) / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z<0.0)\n" + " {\n" + " float r = -te.z / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z>1.0)\n" + " {\n" + " float r = (1.0-te.z) / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + " }\n" + "\n" + " const float max_iteratrions = 2048.0;\n" + " float num_iterations = ceil(length(te-t0)/sampleDensity);\n" + " if (num_iterations<2.0) num_iterations = 2.0;\n" + "\n" + " if (num_iterations>max_iteratrions) \n" + " {\n" + " num_iterations = max_iteratrions;\n" + " }\n" + "\n" + " vec3 deltaTexCoord=(te-t0)/float(num_iterations-1.0);\n" + " vec3 texcoord = t0;\n" + "\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" + " while(num_iterations>0.0)\n" + " {\n" + " vec4 color = texture3D( baseTexture, texcoord);\n" + " float r = color[3]*transparency;\n" + " if (r>alphaCutOff)\n" + " {\n" + " fragColor.xyz = fragColor.xyz*(1.0-r)+color.xyz*r;\n" + " fragColor.w += r;\n" + " }\n" + "\n" + " if (fragColor.w1.0) fragColor.w = 1.0; \n" + " if (fragColor.w=0.0 && te.x<=1.0 &&\n" + " te.y>=0.0 && te.y<=1.0 &&\n" + " te.z>=0.0 && te.z<=1.0)\n" + " {\n" + " // do nothing... te inside volume\n" + " }\n" + " else\n" + " {\n" + " if (te.x<0.0)\n" + " {\n" + " float r = -te.x / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.x>1.0)\n" + " {\n" + " float r = (1.0-te.x) / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y<0.0)\n" + " {\n" + " float r = -te.y / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y>1.0)\n" + " {\n" + " float r = (1.0-te.y) / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z<0.0)\n" + " {\n" + " float r = -te.z / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z>1.0)\n" + " {\n" + " float r = (1.0-te.z) / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + " }\n" + "\n" + " const float max_iteratrions = 2048.0;\n" + " float num_iterations = ceil(length(te-t0)/sampleDensity);\n" + " if (num_iterations<2.0) num_iterations = 2.0;\n" + "\n" + " if (num_iterations>max_iteratrions) \n" + " {\n" + " num_iterations = max_iteratrions;\n" + " }\n" + "\n" + " vec3 deltaTexCoord=(t0-te)/float(num_iterations-1.0);\n" + " vec3 texcoord = te;\n" + "\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" + " vec4 previousColor = texture3D( baseTexture, texcoord);\n" + " \n" + " float normalSampleDistance = 1.0/512.0;\n" + " vec3 deltaX = vec3(normalSampleDistance, 0.0, 0.0);\n" + " vec3 deltaY = vec3(0.0, normalSampleDistance, 0.0);\n" + " vec3 deltaZ = vec3(0.0, 0.0, normalSampleDistance);\n" + " \n" + " while(num_iterations>0.0)\n" + " {\n" + " vec4 color = texture3D( baseTexture, texcoord);\n" + "\n" + " float m = (previousColor.a-alphaCutOff) * (color.a-alphaCutOff);\n" + " if (m <= 0.0)\n" + " {\n" + " float r = (alphaCutOff-color.a)/(previousColor.a-color.a);\n" + " texcoord = texcoord - r*deltaTexCoord;\n" + " \n" + " float a = color.a;\n" + " float px = texture3D( baseTexture, texcoord + deltaX).a;\n" + " float py = texture3D( baseTexture, texcoord + deltaY).a;\n" + " float pz = texture3D( baseTexture, texcoord + deltaZ).a;\n" + "\n" + " float nx = texture3D( baseTexture, texcoord - deltaX).a;\n" + " float ny = texture3D( baseTexture, texcoord - deltaY).a;\n" + " float nz = texture3D( baseTexture, texcoord - deltaZ).a;\n" + " \n" + " vec3 grad = vec3(px-nx, py-ny, pz-nz);\n" + " vec3 normal = normalize(grad);\n" + "\n" + " float lightScale = 0.1 + abs(dot(normal.xyz, eyeDirection))*0.9;\n" + " \n" + " \n" + "#if 0\n" + " color.x *= lightScale;\n" + " color.y *= lightScale;\n" + " color.z *= lightScale;\n" + "#else\n" + " color.x = lightScale;\n" + " color.y = lightScale;\n" + " color.z = lightScale;\n" + "#endif\n" + "\n" + " fragColor = vec4(lightScale, lightScale, lightScale, 1.0);\n" + " \n" + " break;\n" + " }\n" + " \n" + " previousColor = color;\n" + " \n" + " texcoord += deltaTexCoord; \n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " if (fragColor.w>1.0) fragColor.w = 1.0; \n" + " //if (fragColor.w=0.0 && te.x<=1.0 &&\n" + " te.y>=0.0 && te.y<=1.0 &&\n" + " te.z>=0.0 && te.z<=1.0)\n" + " {\n" + " // do nothing... te inside volume\n" + " }\n" + " else\n" + " {\n" + " if (te.x<0.0)\n" + " {\n" + " float r = -te.x / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.x>1.0)\n" + " {\n" + " float r = (1.0-te.x) / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y<0.0)\n" + " {\n" + " float r = -te.y / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y>1.0)\n" + " {\n" + " float r = (1.0-te.y) / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z<0.0)\n" + " {\n" + " float r = -te.z / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z>1.0)\n" + " {\n" + " float r = (1.0-te.z) / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + " }\n" + "\n" + " const float max_iteratrions = 2048.0;\n" + " float num_iterations = ceil(length(te-t0)/sampleDensity);\n" + " if (num_iterations<2.0) num_iterations = 2.0;\n" + "\n" + " if (num_iterations>max_iteratrions) \n" + " {\n" + " num_iterations = max_iteratrions;\n" + " }\n" + "\n" + " vec3 deltaTexCoord=(te-t0)/float(num_iterations-1.0);\n" + " vec3 texcoord = t0;\n" + "\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" + " while(num_iterations>0.0)\n" + " {\n" + " vec4 color = texture3D( baseTexture, texcoord);\n" + " if (fragColor.w1.0) fragColor.w = 1.0; \n" + " if (fragColor.w=0.0 && te.x<=1.0 &&\n" + " te.y>=0.0 && te.y<=1.0 &&\n" + " te.z>=0.0 && te.z<=1.0)\n" + " {\n" + " // do nothing... te inside volume\n" + " }\n" + " else\n" + " {\n" + " if (te.x<0.0)\n" + " {\n" + " float r = -te.x / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.x>1.0)\n" + " {\n" + " float r = (1.0-te.x) / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y<0.0)\n" + " {\n" + " float r = -te.y / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y>1.0)\n" + " {\n" + " float r = (1.0-te.y) / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z<0.0)\n" + " {\n" + " float r = -te.z / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z>1.0)\n" + " {\n" + " float r = (1.0-te.z) / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + " }\n" + "\n" + " const float max_iteratrions = 2048.0;\n" + " float num_iterations = ceil(length(te-t0)/sampleDensity);\n" + " if (num_iterations<2.0) num_iterations = 2.0;\n" + "\n" + " if (num_iterations>max_iteratrions) \n" + " {\n" + " num_iterations = max_iteratrions;\n" + " }\n" + "\n" + " vec3 deltaTexCoord=(te-t0)/float(num_iterations-1.0);\n" + " vec3 texcoord = t0;\n" + "\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" + " while(num_iterations>0.0)\n" + " {\n" + " vec4 normal = texture3D( normalMap, texcoord);\n" + "#if 1\n" + " vec4 color = texture3D( baseTexture, texcoord);\n" + "\n" + " normal.x = normal.x*2.0-1.0;\n" + " normal.y = normal.y*2.0-1.0;\n" + " normal.z = normal.z*2.0-1.0;\n" + " \n" + " float lightScale = 0.1 + max(dot(normal.xyz, eyeDirection), 0.0);\n" + " color.x *= lightScale;\n" + " color.y *= lightScale;\n" + " color.z *= lightScale;\n" + "\n" + " float r = normal[3]*transparency;\n" + "#else\n" + " vec4 color = texture3D( normalMap, texcoord);\n" + " color.x = color.x*2.0 - 1.0;\n" + " color.y = color.y*2.0 - 1.0;\n" + " color.z = color.z*2.0 - 1.0;\n" + " \n" + " float lightScale = 0.1 + max(dot(color.xyz, eyeDirection), 0.0);\n" + " color.x = lightScale;\n" + " color.y = lightScale;\n" + " color.z = lightScale;\n" + "\n" + " float r = color[3]*transparency;\n" + "#endif \n" + " if (r>alphaCutOff)\n" + " {\n" + " fragColor.xyz = fragColor.xyz*(1.0-r)+color.xyz*r;\n" + " fragColor.w += r;\n" + " }\n" + " texcoord += deltaTexCoord; \n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " if (fragColor.w>1.0) fragColor.w = 1.0; \n" + " if (fragColor.w==0.0) discard;\n" + " gl_FragColor = fragColor;\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_tf_frag.cpp b/src/osgVolume/Shaders/volume_tf_frag.cpp new file mode 100644 index 000000000..b0d0729d2 --- /dev/null +++ b/src/osgVolume/Shaders/volume_tf_frag.cpp @@ -0,0 +1,102 @@ +char volume_tf_frag[] = "uniform sampler3D baseTexture;\n" + "uniform sampler1D tfTexture;\n" + "uniform float sampleDensity;\n" + "uniform float transparency;\n" + "uniform float alphaCutOff;\n" + "\n" + "varying vec4 cameraPos;\n" + "varying vec4 vertexPos;\n" + "varying mat4 texgen;\n" + "\n" + "void main(void)\n" + "{ \n" + " vec3 t0 = (texgen * vertexPos).xyz;\n" + " vec3 te = (texgen * cameraPos).xyz;\n" + "\n" + " if (te.x>=0.0 && te.x<=1.0 &&\n" + " te.y>=0.0 && te.y<=1.0 &&\n" + " te.z>=0.0 && te.z<=1.0)\n" + " {\n" + " // do nothing... te inside volume\n" + " }\n" + " else\n" + " {\n" + " if (te.x<0.0)\n" + " {\n" + " float r = -te.x / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.x>1.0)\n" + " {\n" + " float r = (1.0-te.x) / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y<0.0)\n" + " {\n" + " float r = -te.y / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y>1.0)\n" + " {\n" + " float r = (1.0-te.y) / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z<0.0)\n" + " {\n" + " float r = -te.z / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z>1.0)\n" + " {\n" + " float r = (1.0-te.z) / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + " }\n" + "\n" + " const float max_iteratrions = 2048.0;\n" + " float num_iterations = ceil(length(te-t0)/sampleDensity);\n" + " if (num_iterations<2.0) num_iterations = 2.0;\n" + "\n" + " if (num_iterations>max_iteratrions) \n" + " {\n" + " num_iterations = max_iteratrions;\n" + " }\n" + "\n" + " vec3 deltaTexCoord=(te-t0)/float(num_iterations-1.0);\n" + " vec3 texcoord = t0;\n" + "\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" + " while(num_iterations>0.0)\n" + " {\n" + " float v = texture3D( baseTexture, texcoord).a;\n" + " vec4 color = texture1D( tfTexture, v);\n" + "\n" + " float r = color[3]*transparency;\n" + " if (r>alphaCutOff)\n" + " {\n" + " fragColor.xyz = fragColor.xyz*(1.0-r)+color.xyz*r;\n" + " fragColor.w += r;\n" + " }\n" + "\n" + " if (fragColor.w1.0) fragColor.w = 1.0; \n" + " if (fragColor.w=0.0 && te.x<=1.0 &&\n" + " te.y>=0.0 && te.y<=1.0 &&\n" + " te.z>=0.0 && te.z<=1.0)\n" + " {\n" + " // do nothing... te inside volume\n" + " }\n" + " else\n" + " {\n" + " if (te.x<0.0)\n" + " {\n" + " float r = -te.x / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.x>1.0)\n" + " {\n" + " float r = (1.0-te.x) / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y<0.0)\n" + " {\n" + " float r = -te.y / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y>1.0)\n" + " {\n" + " float r = (1.0-te.y) / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z<0.0)\n" + " {\n" + " float r = -te.z / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z>1.0)\n" + " {\n" + " float r = (1.0-te.z) / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + " }\n" + "\n" + " const float max_iteratrions = 2048.0;\n" + " float num_iterations = ceil(length(te-t0)/sampleDensity);\n" + " if (num_iterations<2.0) num_iterations = 2.0;\n" + " \n" + " if (num_iterations>max_iteratrions) \n" + " {\n" + " num_iterations = max_iteratrions;\n" + " }\n" + "\n" + " vec3 deltaTexCoord=(t0-te)/float(num_iterations-1.0);\n" + " vec3 texcoord = te;\n" + " float previousV = texture3D( baseTexture, texcoord).a;\n" + "\n" + " float normalSampleDistance = 1.0/512.0;\n" + " vec3 deltaX = vec3(normalSampleDistance, 0.0, 0.0);\n" + " vec3 deltaY = vec3(0.0, normalSampleDistance, 0.0);\n" + " vec3 deltaZ = vec3(0.0, 0.0, normalSampleDistance);\n" + "\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" + " while(num_iterations>0.0)\n" + " {\n" + "\n" + " float v = texture3D( baseTexture, texcoord).a;\n" + "\n" + " float m = (previousV-alphaCutOff) * (v-alphaCutOff);\n" + " if (m <= 0.0)\n" + " {\n" + " float r = (alphaCutOff-v)/(previousV-v);\n" + " texcoord = texcoord - r*deltaTexCoord;\n" + "\n" + " v = texture3D( baseTexture, texcoord).a;\n" + " vec4 color = texture1D( tfTexture, v);\n" + "\n" + " float px = texture3D( baseTexture, texcoord + deltaX).a;\n" + " float py = texture3D( baseTexture, texcoord + deltaY).a;\n" + " float pz = texture3D( baseTexture, texcoord + deltaZ).a;\n" + "\n" + " float nx = texture3D( baseTexture, texcoord - deltaX).a;\n" + " float ny = texture3D( baseTexture, texcoord - deltaY).a;\n" + " float nz = texture3D( baseTexture, texcoord - deltaZ).a;\n" + " \n" + " vec3 grad = vec3(px-nx, py-ny, pz-nz);\n" + " vec3 normal = normalize(grad);\n" + "\n" + " float lightScale = 0.1 + abs(dot(normal.xyz, eyeDirection))*0.9;\n" + " \n" + " color.x *= lightScale;\n" + " color.y *= lightScale;\n" + " color.z *= lightScale;\n" + "\n" + " fragColor = color;\n" + " \n" + " break;\n" + " }\n" + " \n" + " previousV = v;\n" + " \n" + " texcoord += deltaTexCoord; \n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " if (fragColor.w>1.0) fragColor.w = 1.0; \n" + " if (fragColor.w=0.0 && te.x<=1.0 &&\n" + " te.y>=0.0 && te.y<=1.0 &&\n" + " te.z>=0.0 && te.z<=1.0)\n" + " {\n" + " // do nothing... te inside volume\n" + " }\n" + " else\n" + " {\n" + " if (te.x<0.0)\n" + " {\n" + " float r = -te.x / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.x>1.0)\n" + " {\n" + " float r = (1.0-te.x) / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y<0.0)\n" + " {\n" + " float r = -te.y / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y>1.0)\n" + " {\n" + " float r = (1.0-te.y) / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z<0.0)\n" + " {\n" + " float r = -te.z / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z>1.0)\n" + " {\n" + " float r = (1.0-te.z) / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + " }\n" + "\n" + " const float max_iteratrions = 2048.0;\n" + " float num_iterations = ceil(length(te-t0)/sampleDensity);\n" + " if (num_iterations<2.0) num_iterations = 2.0;\n" + " \n" + " if (num_iterations>max_iteratrions) \n" + " {\n" + " num_iterations = max_iteratrions;\n" + " }\n" + "\n" + " vec3 deltaTexCoord=(te-t0)/float(num_iterations-1.0);\n" + " vec3 texcoord = t0;\n" + "\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" + " while(num_iterations>0.0)\n" + " {\n" + " float v = texture3D( baseTexture, texcoord).s;\n" + " vec4 color = texture1D( tfTexture, v);\n" + " if (fragColor.w1.0) fragColor.w = 1.0; \n" + " if (fragColor.w=0.0 && te.x<=1.0 &&\n" + " te.y>=0.0 && te.y<=1.0 &&\n" + " te.z>=0.0 && te.z<=1.0)\n" + " {\n" + " // do nothing... te inside volume\n" + " }\n" + " else\n" + " {\n" + " if (te.x<0.0)\n" + " {\n" + " float r = -te.x / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.x>1.0)\n" + " {\n" + " float r = (1.0-te.x) / (t0.x-te.x);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y<0.0)\n" + " {\n" + " float r = -te.y / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.y>1.0)\n" + " {\n" + " float r = (1.0-te.y) / (t0.y-te.y);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z<0.0)\n" + " {\n" + " float r = -te.z / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + "\n" + " if (te.z>1.0)\n" + " {\n" + " float r = (1.0-te.z) / (t0.z-te.z);\n" + " te = te + (t0-te)*r;\n" + " }\n" + " }\n" + "\n" + " const float max_iteratrions = 2048.0;\n" + " float num_iterations = ceil(length(te-t0)/sampleDensity);\n" + " if (num_iterations<2.0) num_iterations = 2.0;\n" + " \n" + " if (num_iterations>max_iteratrions) \n" + " {\n" + " num_iterations = max_iteratrions;\n" + " }\n" + "\n" + " vec3 deltaTexCoord=(te-t0)/float(num_iterations-1.0);\n" + " vec3 texcoord = t0;\n" + "\n" + " vec4 fragColor = vec4(0.0, 0.0, 0.0, 0.0); \n" + " while(num_iterations>0.0)\n" + " {\n" + " vec4 normal = texture3D( normalMap, texcoord);\n" + " float v = normal.a; // texture3D( baseTexture, texcoord).s;\n" + " vec4 color = texture1D( tfTexture, v);\n" + "\n" + " normal.x = normal.x*2.0-1.0;\n" + " normal.y = normal.y*2.0-1.0;\n" + " normal.z = normal.z*2.0-1.0;\n" + " \n" + " float lightScale = 0.1 + max(dot(normal.xyz, eyeDirection), 0.0);\n" + " color.x *= lightScale;\n" + " color.y *= lightScale;\n" + " color.z *= lightScale;\n" + "\n" + " float r = normal[3]*transparency;\n" + " if (r>alphaCutOff)\n" + " {\n" + " fragColor.xyz = fragColor.xyz*(1.0-r)+color.xyz*r;\n" + " fragColor.w += r;\n" + " }\n" + " texcoord += deltaTexCoord; \n" + "\n" + " --num_iterations;\n" + " }\n" + "\n" + " if (fragColor.w>1.0) fragColor.w = 1.0; \n" + " if (fragColor.w==0.0) discard;\n" + " gl_FragColor = fragColor;\n" + "}\n" + "\n"; diff --git a/src/osgVolume/Shaders/volume_vert.cpp b/src/osgVolume/Shaders/volume_vert.cpp new file mode 100644 index 000000000..acd07276d --- /dev/null +++ b/src/osgVolume/Shaders/volume_vert.cpp @@ -0,0 +1,17 @@ +char volume_vert[] = "#version 110\n" + "varying vec4 cameraPos;\n" + "varying vec4 vertexPos;\n" + "varying mat4 texgen;\n" + "\n" + "void main(void)\n" + "{\n" + " gl_Position = ftransform();\n" + "\n" + " cameraPos = gl_ModelViewMatrixInverse*vec4(0,0,0,1);\n" + " vertexPos = gl_Vertex;\n" + "\n" + " texgen = mat4(gl_ObjectPlaneS[0], \n" + " gl_ObjectPlaneT[0],\n" + " gl_ObjectPlaneR[0],\n" + " gl_ObjectPlaneQ[0]);\n" + "}\n"; diff --git a/src/osgVolume/VolumeTile.cpp b/src/osgVolume/VolumeTile.cpp index 208a655b7..2c6863313 100644 --- a/src/osgVolume/VolumeTile.cpp +++ b/src/osgVolume/VolumeTile.cpp @@ -167,7 +167,14 @@ osg::BoundingSphere VolumeTile::computeBound() const { osg::BoundingSphere bs; - osg::notify(osg::NOTICE)<<"TODO VolumeTile::computeBound()"<valid()) bs.expandBy((*itr)->computeBound()); + } return bs; + + return bs; }