Further work on new MultipassTechnique/VolumeScene.
This commit is contained in:
@@ -1225,12 +1225,12 @@ int main( int argc, char **argv )
|
||||
{
|
||||
osg::ref_ptr<osgVolume::VolumeScene> volumeScene = new osgVolume::VolumeScene;
|
||||
volumeScene->addChild(loadedModel.get());
|
||||
loadedModel->getOrCreateStateSet();
|
||||
loadedModel = volumeScene.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// set the scene to render
|
||||
viewer.setSceneData(loadedModel.get());
|
||||
|
||||
|
||||
@@ -320,12 +320,12 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac
|
||||
else acceptNode->accept(*this);
|
||||
}
|
||||
|
||||
osg::ref_ptr<StateGraph> _rootStateGraph;
|
||||
StateGraph* _currentStateGraph;
|
||||
osg::ref_ptr<StateGraph> _rootStateGraph;
|
||||
StateGraph* _currentStateGraph;
|
||||
|
||||
osg::ref_ptr<RenderStage> _rootRenderStage;
|
||||
RenderBin* _currentRenderBin;
|
||||
std::vector<RenderBin*> _renderBinStack;
|
||||
osg::ref_ptr<RenderStage> _rootRenderStage;
|
||||
RenderBin* _currentRenderBin;
|
||||
std::vector<RenderBin*> _renderBinStack;
|
||||
|
||||
unsigned int _traversalNumber;
|
||||
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
#include <osgVolume/Export>
|
||||
|
||||
#include <osg/Object>
|
||||
#include <osg/observer_ptr>
|
||||
#include <osg/Matrixd>
|
||||
#include <osg/TexGen>
|
||||
#include <osg/MatrixTransform>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -95,6 +98,36 @@ class OSGVOLUME_EXPORT Locator : public osg::Object
|
||||
LocatorCallbacks _locatorCallbacks;
|
||||
};
|
||||
|
||||
class OSGVOLUME_EXPORT TransformLocatorCallback : public Locator::LocatorCallback
|
||||
{
|
||||
public:
|
||||
|
||||
TransformLocatorCallback(osg::MatrixTransform* transform);
|
||||
|
||||
void locatorModified(Locator* locator);
|
||||
|
||||
protected:
|
||||
|
||||
osg::observer_ptr<osg::MatrixTransform> _transform;
|
||||
};
|
||||
|
||||
|
||||
class OSGVOLUME_EXPORT TexGenLocatorCallback : public Locator::LocatorCallback
|
||||
{
|
||||
public:
|
||||
|
||||
TexGenLocatorCallback(osg::TexGen* texgen, Locator* geometryLocator, Locator* imageLocator);
|
||||
|
||||
void locatorModified(Locator*);
|
||||
|
||||
protected:
|
||||
|
||||
osg::observer_ptr<osg::TexGen> _texgen;
|
||||
osg::observer_ptr<osgVolume::Locator> _geometryLocator;
|
||||
osg::observer_ptr<osgVolume::Locator> _imageLocator;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,18 +42,29 @@ class OSGVOLUME_EXPORT VolumeScene : public osg::Group
|
||||
|
||||
virtual ~VolumeScene();
|
||||
|
||||
struct TileData : public osg::Referenced
|
||||
{
|
||||
osg::NodePath nodePath;
|
||||
osg::ref_ptr<osg::RefMatrix> projectionMatrix;
|
||||
osg::ref_ptr<osg::RefMatrix> modelviewMatrix;
|
||||
};
|
||||
typedef std::list< osg::ref_ptr<TileData> > Tiles;
|
||||
|
||||
class ViewData : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
ViewData();
|
||||
osg::ref_ptr<osg::Texture2D> _depthTexture;
|
||||
osg::ref_ptr<osg::Texture2D> _colorTexture;
|
||||
osg::ref_ptr<osg::Camera> _rttCamera;
|
||||
osg::ref_ptr<osg::Camera> _postCamera;
|
||||
osg::ref_ptr<osgUtil::RenderStage> _parentRenderStage;
|
||||
osg::ref_ptr<osg::Texture2D> _depthTexture;
|
||||
osg::ref_ptr<osg::Texture2D> _colorTexture;
|
||||
osg::ref_ptr<osg::Camera> _rttCamera;
|
||||
osg::ref_ptr<osg::Node> _backdropSubgraph;
|
||||
osg::ref_ptr<osg::Geometry> _geometry;
|
||||
osg::ref_ptr<osg::Vec3Array> _vertices;
|
||||
osg::ref_ptr<osg::StateSet> _stateset;
|
||||
osg::ref_ptr<osg::Uniform> _viewportSizeUniform;
|
||||
|
||||
Tiles _tiles;
|
||||
|
||||
typedef std::list< osg::NodePath > Tiles;
|
||||
Tiles _tiles;
|
||||
protected:
|
||||
virtual ~ViewData() {}
|
||||
};
|
||||
|
||||
@@ -222,3 +222,35 @@ void Locator::locatorModified()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TransformLocatorCallback
|
||||
//
|
||||
TransformLocatorCallback::TransformLocatorCallback(osg::MatrixTransform* transform):
|
||||
_transform(transform)
|
||||
{}
|
||||
|
||||
void TransformLocatorCallback::locatorModified(Locator* locator)
|
||||
{
|
||||
if (_transform.valid()) _transform->setMatrix(locator->getTransform());
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TexGenLocatorCallback
|
||||
//
|
||||
TexGenLocatorCallback::TexGenLocatorCallback(osg::TexGen* texgen, Locator* geometryLocator, Locator* imageLocator):
|
||||
_texgen(texgen),
|
||||
_geometryLocator(geometryLocator),
|
||||
_imageLocator(imageLocator) {}
|
||||
|
||||
void TexGenLocatorCallback::locatorModified(Locator*)
|
||||
{
|
||||
if (!_texgen || !_geometryLocator || !_imageLocator) return;
|
||||
|
||||
_texgen->setPlanesFromMatrix(
|
||||
_geometryLocator->getTransform() *
|
||||
osg::Matrix::inverse(_imageLocator->getTransform()));
|
||||
}
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
#include <osgVolume/VolumeScene>
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/ValueObject>
|
||||
#include <osg/io_utils>
|
||||
|
||||
#include <osg/Program>
|
||||
#include <osg/Material>
|
||||
#include <osg/CullFace>
|
||||
#include <osg/TexGen>
|
||||
#include <osg/Texture1D>
|
||||
#include <osg/Texture2D>
|
||||
@@ -68,6 +71,297 @@ void MultipassTechnique::init()
|
||||
}
|
||||
|
||||
OSG_NOTICE<<"MultipassTechnique::init() Need to set up"<<std::endl;
|
||||
|
||||
CollectPropertiesVisitor cpv;
|
||||
if (_volumeTile->getLayer()->getProperty())
|
||||
{
|
||||
_volumeTile->getLayer()->getProperty()->accept(cpv);
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||
|
||||
{
|
||||
osg::Geometry* geom = new osg::Geometry;
|
||||
|
||||
osg::Vec3Array* coords = new osg::Vec3Array(8);
|
||||
(*coords)[0] = osg::Vec3d(0.0,0.0,0.0);
|
||||
(*coords)[1] = osg::Vec3d(1.0,0.0,0.0);
|
||||
(*coords)[2] = osg::Vec3d(1.0,1.0,0.0);
|
||||
(*coords)[3] = osg::Vec3d(0.0,1.0,0.0);
|
||||
(*coords)[4] = osg::Vec3d(0.0,0.0,1.0);
|
||||
(*coords)[5] = osg::Vec3d(1.0,0.0,1.0);
|
||||
(*coords)[6] = osg::Vec3d(1.0,1.0,1.0);
|
||||
(*coords)[7] = osg::Vec3d(0.0,1.0,1.0);
|
||||
geom->setVertexArray(coords);
|
||||
|
||||
osg::Vec4Array* colours = new osg::Vec4Array(1);
|
||||
(*colours)[0].set(1.0f,1.0f,1.0,1.0f);
|
||||
geom->setColorArray(colours, osg::Array::BIND_OVERALL);
|
||||
|
||||
osg::DrawElementsUShort* drawElements = new osg::DrawElementsUShort(GL_QUADS);
|
||||
// bottom
|
||||
drawElements->push_back(3);
|
||||
drawElements->push_back(2);
|
||||
drawElements->push_back(1);
|
||||
drawElements->push_back(0);
|
||||
|
||||
// bottom
|
||||
drawElements->push_back(7);//7623
|
||||
drawElements->push_back(6);
|
||||
drawElements->push_back(2);
|
||||
drawElements->push_back(3);
|
||||
|
||||
// left
|
||||
drawElements->push_back(4);//4730
|
||||
drawElements->push_back(7);
|
||||
drawElements->push_back(3);
|
||||
drawElements->push_back(0);
|
||||
|
||||
// right
|
||||
drawElements->push_back(1);//1265
|
||||
drawElements->push_back(2);
|
||||
drawElements->push_back(6);
|
||||
drawElements->push_back(5);
|
||||
|
||||
// front
|
||||
drawElements->push_back(5);//5401
|
||||
drawElements->push_back(4);
|
||||
drawElements->push_back(0);
|
||||
drawElements->push_back(1);
|
||||
|
||||
// top
|
||||
drawElements->push_back(4);//4567
|
||||
drawElements->push_back(5);
|
||||
drawElements->push_back(6);
|
||||
drawElements->push_back(7);
|
||||
|
||||
geom->addPrimitiveSet(drawElements);
|
||||
|
||||
geode->addDrawable(geom);
|
||||
|
||||
}
|
||||
|
||||
_transform = new osg::MatrixTransform;
|
||||
|
||||
// handle locators
|
||||
Locator* masterLocator = _volumeTile->getLocator();
|
||||
Locator* layerLocator = _volumeTile->getLayer()->getLocator();
|
||||
|
||||
if (!masterLocator && layerLocator) masterLocator = layerLocator;
|
||||
if (!layerLocator && masterLocator) layerLocator = masterLocator;
|
||||
|
||||
osg::Matrix geometryMatrix;
|
||||
if (masterLocator)
|
||||
{
|
||||
geometryMatrix = masterLocator->getTransform();
|
||||
_transform->setMatrix(geometryMatrix);
|
||||
masterLocator->addCallback(new TransformLocatorCallback(_transform.get()));
|
||||
}
|
||||
|
||||
osg::Matrix imageMatrix;
|
||||
if (layerLocator)
|
||||
{
|
||||
imageMatrix = layerLocator->getTransform();
|
||||
}
|
||||
|
||||
OSG_NOTICE<<"MultipassTechnique::init() : geometryMatrix = "<<geometryMatrix<<std::endl;
|
||||
OSG_NOTICE<<"MultipassTechnique::init() : imageMatrix = "<<imageMatrix<<std::endl;
|
||||
|
||||
osg::ref_ptr<osg::StateSet> stateset = _transform->getOrCreateStateSet();
|
||||
|
||||
unsigned int texgenTextureUnit = 0;
|
||||
unsigned int volumeTextureUnit = 2;
|
||||
|
||||
// set up uniforms
|
||||
{
|
||||
stateset->addUniform(new osg::Uniform("colorTexture",0));
|
||||
stateset->addUniform(new osg::Uniform("depthTexture",1));
|
||||
|
||||
stateset->setMode(GL_ALPHA_TEST,osg::StateAttribute::ON);
|
||||
|
||||
float alphaFuncValue = 0.1;
|
||||
if (cpv._isoProperty.valid())
|
||||
{
|
||||
alphaFuncValue = cpv._isoProperty->getValue();
|
||||
}
|
||||
|
||||
if (cpv._sampleDensityProperty.valid())
|
||||
stateset->addUniform(cpv._sampleDensityProperty->getUniform());
|
||||
else
|
||||
stateset->addUniform(new osg::Uniform("SampleDensityValue",0.0005f));
|
||||
|
||||
|
||||
if (cpv._transparencyProperty.valid())
|
||||
stateset->addUniform(cpv._transparencyProperty->getUniform());
|
||||
else
|
||||
stateset->addUniform(new osg::Uniform("TransparencyValue",1.0f));
|
||||
|
||||
|
||||
if (cpv._afProperty.valid())
|
||||
stateset->addUniform(cpv._afProperty->getUniform());
|
||||
else
|
||||
stateset->addUniform(new osg::Uniform("AlphaFuncValue",alphaFuncValue));
|
||||
|
||||
#if 1
|
||||
osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen;
|
||||
texgen->setMode(osg::TexGen::OBJECT_LINEAR);
|
||||
texgen->setPlanesFromMatrix( geometryMatrix * osg::Matrix::inverse(imageMatrix));
|
||||
|
||||
if (masterLocator)
|
||||
{
|
||||
osg::ref_ptr<TexGenLocatorCallback> locatorCallback = new TexGenLocatorCallback(texgen, masterLocator, layerLocator);
|
||||
masterLocator->addCallback(locatorCallback.get());
|
||||
if (masterLocator != layerLocator)
|
||||
{
|
||||
if (layerLocator) layerLocator->addCallback(locatorCallback.get());
|
||||
}
|
||||
}
|
||||
|
||||
stateset->setTextureAttributeAndModes(texgenTextureUnit, texgen.get(), osg::StateAttribute::ON);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// set up 3D texture
|
||||
osg::ref_ptr<osg::Image> image_3d = _volumeTile->getLayer()->getImage();
|
||||
osg::ref_ptr<osg::Texture3D> texture3D = new osg::Texture3D;
|
||||
{
|
||||
osg::Texture::InternalFormatMode internalFormatMode = osg::Texture::USE_IMAGE_DATA_FORMAT;
|
||||
osg::Texture::FilterMode minFilter = osg::Texture::LINEAR;
|
||||
osg::Texture::FilterMode magFilter = osg::Texture::LINEAR;
|
||||
|
||||
// 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.
|
||||
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_BORDER);
|
||||
texture3D->setWrap(osg::Texture3D::WRAP_S,osg::Texture3D::CLAMP_TO_BORDER);
|
||||
texture3D->setWrap(osg::Texture3D::WRAP_T,osg::Texture3D::CLAMP_TO_BORDER);
|
||||
texture3D->setBorderColor(osg::Vec4(0.0,0.0,0.0,0.0));
|
||||
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(volumeTextureUnit, texture3D, osg::StateAttribute::ON);
|
||||
|
||||
osg::Uniform* baseTextureSampler = new osg::Uniform("volumeTexture", int(volumeTextureUnit));
|
||||
stateset->addUniform(baseTextureSampler);
|
||||
}
|
||||
|
||||
|
||||
|
||||
osg::ref_ptr<osg::Shader> computeRayColorShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, "shaders/volume_compute_ray_color.frag");
|
||||
#if 0
|
||||
if (!computeRayColorShader)
|
||||
{
|
||||
#include "Shaders/volume_compute_ray_color_frag.cpp";
|
||||
computeRayColorShader = new osg::Shader(osg::Shader::FRAGMENT, volume_compute_ray_color_frag);
|
||||
}
|
||||
#endif
|
||||
|
||||
// set up the renderin of the front faces
|
||||
{
|
||||
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
|
||||
else
|
||||
{
|
||||
#include "Shaders/volume_color_depth_vert.cpp"
|
||||
program->addShader(new osg::Shader(osg::Shader::VERTEX, volume_color_depth_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
|
||||
|
||||
if (computeRayColorShader.valid())
|
||||
{
|
||||
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
|
||||
else
|
||||
{
|
||||
#include "Shaders/volume_color_depth_vert.cpp"
|
||||
program->addShader(new osg::Shader(osg::Shader::VERTEX, volume_color_depth_vert));
|
||||
}
|
||||
#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())
|
||||
{
|
||||
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
|
||||
if (computeRayColorShader.valid())
|
||||
{
|
||||
program->addShader(computeRayColorShader.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MultipassTechnique::update(osgUtil::UpdateVisitor* /*uv*/)
|
||||
@@ -77,19 +371,29 @@ void MultipassTechnique::update(osgUtil::UpdateVisitor* /*uv*/)
|
||||
|
||||
void MultipassTechnique::cull(osgUtil::CullVisitor* cv)
|
||||
{
|
||||
OSG_NOTICE<<"MultipassTechnique::cull() Need to set up"<<std::endl;
|
||||
osg::NodePath& nodePath = cv->getNodePath();
|
||||
for(osg::NodePath::reverse_iterator itr = nodePath.rbegin();
|
||||
itr != nodePath.rend();
|
||||
++itr)
|
||||
std::string traversalPass;
|
||||
bool postTraversal = cv->getUserValue("VolumeSceneTraversal", traversalPass) && traversalPass=="Post";
|
||||
|
||||
// OSG_NOTICE<<"MultipassTechnique::cull() traversalPass="<<traversalPass<<std::endl;
|
||||
|
||||
if (postTraversal)
|
||||
{
|
||||
OSG_NOTICE<<" parent path node "<<*itr<<" "<<(*itr)->className()<<std::endl;
|
||||
osgVolume::VolumeScene* vs = dynamic_cast<osgVolume::VolumeScene*>(*itr);
|
||||
if (vs)
|
||||
// OSG_NOTICE<<" OK need to handle postTraversal"<<std::endl;
|
||||
_transform->accept(*cv);
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::NodePath& nodePath = cv->getNodePath();
|
||||
for(osg::NodePath::reverse_iterator itr = nodePath.rbegin();
|
||||
itr != nodePath.rend();
|
||||
++itr)
|
||||
{
|
||||
OSG_NOTICE<<" HAVE VolumeScene"<<std::endl;
|
||||
vs->tileVisited(cv, getVolumeTile());
|
||||
break;
|
||||
osgVolume::VolumeScene* vs = dynamic_cast<osgVolume::VolumeScene*>(*itr);
|
||||
if (vs)
|
||||
{
|
||||
vs->tileVisited(cv, getVolumeTile());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,49 +30,6 @@
|
||||
namespace osgVolume
|
||||
{
|
||||
|
||||
class TransformLocatorCallback : public Locator::LocatorCallback
|
||||
{
|
||||
public:
|
||||
|
||||
TransformLocatorCallback(osg::MatrixTransform* transform): _transform(transform) {}
|
||||
|
||||
void locatorModified(Locator* locator)
|
||||
{
|
||||
if (_transform.valid()) _transform->setMatrix(locator->getTransform());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
osg::observer_ptr<osg::MatrixTransform> _transform;
|
||||
};
|
||||
|
||||
|
||||
class TexGenLocatorCallback : public Locator::LocatorCallback
|
||||
{
|
||||
public:
|
||||
|
||||
TexGenLocatorCallback(osg::TexGen* texgen, Locator* geometryLocator, Locator* imageLocator):
|
||||
_texgen(texgen),
|
||||
_geometryLocator(geometryLocator),
|
||||
_imageLocator(imageLocator) {}
|
||||
|
||||
void locatorModified(Locator*)
|
||||
{
|
||||
if (!_texgen || !_geometryLocator || !_imageLocator) return;
|
||||
|
||||
_texgen->setPlanesFromMatrix(
|
||||
_geometryLocator->getTransform() *
|
||||
osg::Matrix::inverse(_imageLocator->getTransform()));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
osg::observer_ptr<osg::TexGen> _texgen;
|
||||
osg::observer_ptr<osgVolume::Locator> _geometryLocator;
|
||||
osg::observer_ptr<osgVolume::Locator> _imageLocator;
|
||||
};
|
||||
|
||||
|
||||
RayTracedTechnique::RayTracedTechnique()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
|
||||
#include <osgVolume/VolumeScene>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/PrimitiveSet>
|
||||
#include <osg/Geode>
|
||||
#include <osg/ValueObject>
|
||||
#include <osg/io_utils>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <OpenThreads/ScopedLock>
|
||||
@@ -29,34 +31,12 @@ class RTTCameraCullCallback : public osg::NodeCallback
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
#if 1
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
|
||||
if (cv)
|
||||
{
|
||||
osg::Camera* camera = cv->getCurrentCamera();
|
||||
OSG_NOTICE<<"Current camera="<<camera<<", node="<<node<<std::endl;
|
||||
OSG_NOTICE<<" before near ="<<cv->getCalculatedNearPlane()<<std::endl;
|
||||
OSG_NOTICE<<" before far ="<<cv->getCalculatedFarPlane()<<std::endl;
|
||||
}
|
||||
|
||||
_volumeScene->osg::Group::traverse(*nv);
|
||||
if (cv)
|
||||
{
|
||||
OSG_NOTICE<<" after near ="<<cv->getCalculatedNearPlane()<<std::endl;
|
||||
OSG_NOTICE<<" after far ="<<cv->getCalculatedFarPlane()<<std::endl;
|
||||
}
|
||||
#else
|
||||
osg::Group* group = dynamic_cast<osg::Group*>(node);
|
||||
if (group)
|
||||
{
|
||||
OSG_NOTICE<<"Traversing RTT subgraph, "<<group->className()<<", "<<nv->className()<<std::endl;
|
||||
group->osg::Group::traverse(*nv);
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_NOTICE<<"Can't traverse RTT subgraph"<<std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
node->setUserValue("CalculatedNearPlane",double(cv->getCalculatedNearPlane()));
|
||||
node->setUserValue("CalculatedFarPlane",double(cv->getCalculatedFarPlane()));
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -64,6 +44,7 @@ class RTTCameraCullCallback : public osg::NodeCallback
|
||||
virtual ~RTTCameraCullCallback() {}
|
||||
|
||||
osgVolume::VolumeScene* _volumeScene;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -100,8 +81,11 @@ void VolumeScene::tileVisited(osg::NodeVisitor* nv, osgVolume::VolumeTile* tile)
|
||||
|
||||
if (viewData.valid())
|
||||
{
|
||||
OSG_NOTICE<<"tileVisited("<<tile<<")"<<std::endl;
|
||||
viewData->_tiles.push_back(nv->getNodePath());
|
||||
osg::ref_ptr<TileData> tileData = new TileData;
|
||||
tileData->nodePath = cv->getNodePath();
|
||||
tileData->projectionMatrix = cv->getProjectionMatrix();
|
||||
tileData->modelviewMatrix = cv->getModelViewMatrix();
|
||||
viewData->_tiles.push_back(tileData.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,7 +113,6 @@ void VolumeScene::traverse(osg::NodeVisitor& nv)
|
||||
{
|
||||
OSG_NOTICE<<"Creating ViewData"<<std::endl;
|
||||
|
||||
|
||||
unsigned textureWidth = 512;
|
||||
unsigned textureHeight = 512;
|
||||
|
||||
@@ -187,14 +170,40 @@ void VolumeScene::traverse(osg::NodeVisitor& nv)
|
||||
|
||||
// create mesh for rendering the RTT textures onto the screen
|
||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||
geode->addDrawable(osg::createTexturedQuadGeometry(osg::Vec3(-1.0f,-1.0f,-1.0f),osg::Vec3(2.0f,0.0f,-1.0f),osg::Vec3(0.0f,2.0f,-1.0f)));
|
||||
geode->setCullingActive(false);
|
||||
|
||||
osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet();
|
||||
viewData->_backdropSubgraph = geode;
|
||||
//geode->addDrawable(osg::createTexturedQuadGeometry(osg::Vec3(-1.0f,-1.0f,-1.0f),osg::Vec3(2.0f,0.0f,-1.0f),osg::Vec3(0.0f,2.0f,-1.0f)));
|
||||
|
||||
stateset->setTextureAttributeAndModes(0, viewData->_colorTexture.get(), osg::StateAttribute::ON);
|
||||
stateset->setTextureAttributeAndModes(1, viewData->_depthTexture.get(), osg::StateAttribute::ON);
|
||||
stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
||||
viewData->_geometry = new osg::Geometry;
|
||||
geode->addDrawable(viewData->_geometry.get());
|
||||
|
||||
viewData->_geometry->setUseDisplayList(false);
|
||||
viewData->_geometry->setUseVertexBufferObjects(false);
|
||||
|
||||
viewData->_vertices = new osg::Vec3Array(4);
|
||||
viewData->_geometry->setVertexArray(viewData->_vertices.get());
|
||||
|
||||
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
|
||||
(*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
|
||||
viewData->_geometry->setColorArray(colors.get(), osg::Array::BIND_OVERALL);
|
||||
|
||||
osg::ref_ptr<osg::Vec2Array> texcoords = new osg::Vec2Array(4);
|
||||
(*texcoords)[0].set(0.0f,1.0f);
|
||||
(*texcoords)[1].set(0.0f,0.0f);
|
||||
(*texcoords)[2].set(1.0f,1.0f);
|
||||
(*texcoords)[3].set(1.0f,0.0f);
|
||||
viewData->_geometry->setTexCoordArray(0, texcoords.get(), osg::Array::BIND_PER_VERTEX);
|
||||
|
||||
viewData->_geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP,0,4));
|
||||
|
||||
|
||||
osg::ref_ptr<osg::StateSet> stateset = viewData->_geometry->getOrCreateStateSet();
|
||||
|
||||
stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
|
||||
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
stateset->setRenderBinDetails(10,"DepthSortedBin");
|
||||
|
||||
osg::ref_ptr<osg::Program> program = new osg::Program;
|
||||
stateset->setAttribute(program);
|
||||
@@ -225,29 +234,37 @@ void VolumeScene::traverse(osg::NodeVisitor& nv)
|
||||
program->addShader(new osg::Shader(osg::Shader::FRAGMENT, volume_color_depth_frag));
|
||||
}
|
||||
#endif
|
||||
stateset->addUniform(new osg::Uniform("colorTexture",0));
|
||||
stateset->addUniform(new osg::Uniform("depthTexture",1));
|
||||
viewData->_stateset = new osg::StateSet;
|
||||
viewData->_stateset->addUniform(new osg::Uniform("colorTexture",0));
|
||||
viewData->_stateset->addUniform(new osg::Uniform("depthTexture",1));
|
||||
|
||||
viewData->_postCamera = new osg::Camera;
|
||||
viewData->_postCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
||||
viewData->_postCamera->addChild(geode);
|
||||
viewData->_stateset->setTextureAttributeAndModes(0, viewData->_colorTexture.get(), osg::StateAttribute::ON);
|
||||
viewData->_stateset->setTextureAttributeAndModes(1, viewData->_depthTexture.get(), osg::StateAttribute::ON);
|
||||
|
||||
viewData->_viewportSizeUniform = new osg::Uniform("viewportSize",osg::Vec2(1280.0,1024.0));
|
||||
viewData->_stateset->addUniform(viewData->_viewportSizeUniform.get());
|
||||
|
||||
geode->setStateSet(viewData->_stateset.get());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_NOTICE<<"Reusing ViewData"<<std::endl;
|
||||
// OSG_NOTICE<<"Reusing ViewData"<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
osg::Matrix projectionMatrix = *(cv->getProjectionMatrix());
|
||||
osg::Matrix modelviewMatrix = *(cv->getModelViewMatrix());
|
||||
|
||||
|
||||
// new frame so need to clear last frames log of VolumeTiles
|
||||
viewData->_tiles.clear();
|
||||
|
||||
// record the parent render stage
|
||||
viewData->_parentRenderStage = cv->getCurrentRenderStage();
|
||||
|
||||
osg::Viewport* viewport = cv->getCurrentRenderStage()->getViewport();
|
||||
if (viewport)
|
||||
{
|
||||
viewData->_viewportSizeUniform->set(osg::Vec2(viewport->width(),viewport->height()));
|
||||
|
||||
if (viewport->width() != viewData->_colorTexture->getTextureWidth() ||
|
||||
viewport->height() != viewData->_colorTexture->getTextureHeight())
|
||||
{
|
||||
@@ -257,7 +274,6 @@ void VolumeScene::traverse(osg::NodeVisitor& nv)
|
||||
viewData->_depthTexture->setTextureSize(viewport->width(), viewport->height());
|
||||
viewData->_depthTexture->dirtyTextureObject();
|
||||
viewData->_rttCamera->setViewport(0, 0, viewport->width(), viewport->height());
|
||||
viewData->_postCamera->setViewport(0, 0, viewport->width(), viewport->height());
|
||||
if (viewData->_rttCamera->getRenderingCache())
|
||||
{
|
||||
viewData->_rttCamera->getRenderingCache()->releaseGLObjects(0);
|
||||
@@ -265,24 +281,126 @@ void VolumeScene::traverse(osg::NodeVisitor& nv)
|
||||
}
|
||||
}
|
||||
|
||||
cv->setUserValue("VolumeSceneTraversal",std::string("RenderToTexture"));
|
||||
|
||||
osg::Camera* parentCamera = cv->getCurrentCamera();
|
||||
viewData->_rttCamera->setClearColor(parentCamera->getClearColor());
|
||||
|
||||
OSG_NOTICE<<"Ready to traverse RTT Camera"<<std::endl;
|
||||
OSG_NOTICE<<" RTT Camera ProjectionMatrix Before "<<viewData->_rttCamera->getProjectionMatrix()<<std::endl;
|
||||
//OSG_NOTICE<<"Ready to traverse RTT Camera"<<std::endl;
|
||||
//OSG_NOTICE<<" RTT Camera ProjectionMatrix Before "<<viewData->_rttCamera->getProjectionMatrix()<<std::endl;
|
||||
viewData->_rttCamera->accept(nv);
|
||||
|
||||
OSG_NOTICE<<" RTT Camera ProjectionMatrix After "<<viewData->_rttCamera->getProjectionMatrix()<<std::endl;
|
||||
OSG_NOTICE<<" cv ProjectionMatrix After "<<*(cv->getProjectionMatrix())<<std::endl;
|
||||
//OSG_NOTICE<<" RTT Camera ProjectionMatrix After "<<viewData->_rttCamera->getProjectionMatrix()<<std::endl;
|
||||
//OSG_NOTICE<<" cv ProjectionMatrix After "<<*(cv->getProjectionMatrix())<<std::endl;
|
||||
|
||||
OSG_NOTICE<<" after RTT near ="<<cv->getCalculatedNearPlane()<<std::endl;
|
||||
OSG_NOTICE<<" after RTT far ="<<cv->getCalculatedFarPlane()<<std::endl;
|
||||
//OSG_NOTICE<<" after RTT near ="<<cv->getCalculatedNearPlane()<<std::endl;
|
||||
//OSG_NOTICE<<" after RTT far ="<<cv->getCalculatedFarPlane()<<std::endl;
|
||||
|
||||
OSG_NOTICE<<"tileVisited()"<<viewData->_tiles.size()<<std::endl;
|
||||
//OSG_NOTICE<<"tileVisited()"<<viewData->_tiles.size()<<std::endl;
|
||||
|
||||
|
||||
OSG_NOTICE<<"Ready to traverse POST Camera"<<std::endl;
|
||||
viewData->_postCamera->accept(nv);
|
||||
double calculatedNearPlane = DBL_MAX;
|
||||
double calculatedFarPlane = -DBL_MAX;
|
||||
if (viewData->_rttCamera->getUserValue("CalculatedNearPlane",calculatedNearPlane) &&
|
||||
viewData->_rttCamera->getUserValue("CalculatedFarPlane",calculatedFarPlane))
|
||||
{
|
||||
calculatedNearPlane *= 0.5;
|
||||
calculatedFarPlane *= 2.0;
|
||||
|
||||
//OSG_NOTICE<<"Got from RTTCamera CalculatedNearPlane="<<calculatedNearPlane<<std::endl;
|
||||
//OSG_NOTICE<<"Got from RTTCamera CalculatedFarPlane="<<calculatedFarPlane<<std::endl;
|
||||
if (calculatedNearPlane < cv->getCalculatedNearPlane()) cv->setCalculatedNearPlane(calculatedNearPlane);
|
||||
if (calculatedFarPlane > cv->getCalculatedFarPlane()) cv->setCalculatedFarPlane(calculatedFarPlane);
|
||||
}
|
||||
|
||||
if (calculatedFarPlane>calculatedNearPlane)
|
||||
{
|
||||
cv->clampProjectionMatrix(projectionMatrix, calculatedNearPlane, calculatedFarPlane);
|
||||
}
|
||||
|
||||
osg::Matrix inv_projectionModelViewMatrix;
|
||||
inv_projectionModelViewMatrix.invert(modelviewMatrix*projectionMatrix);
|
||||
|
||||
double depth = 1.0;
|
||||
osg::Vec3d v00 = osg::Vec3d(-1.0,-1.0,depth)*inv_projectionModelViewMatrix;
|
||||
osg::Vec3d v01 = osg::Vec3d(-1.0,1.0,depth)*inv_projectionModelViewMatrix;
|
||||
osg::Vec3d v10 = osg::Vec3d(1.0,-1.0,depth)*inv_projectionModelViewMatrix;
|
||||
osg::Vec3d v11 = osg::Vec3d(1.0,1.0,depth)*inv_projectionModelViewMatrix;
|
||||
|
||||
// OSG_NOTICE<<"v00= "<<v00<<std::endl;
|
||||
// OSG_NOTICE<<"v01= "<<v01<<std::endl;
|
||||
// OSG_NOTICE<<"v10= "<<v10<<std::endl;
|
||||
// OSG_NOTICE<<"v11= "<<v11<<std::endl;
|
||||
|
||||
(*(viewData->_vertices))[0] = v01;
|
||||
(*(viewData->_vertices))[1] = v00;
|
||||
(*(viewData->_vertices))[2] = v11;
|
||||
(*(viewData->_vertices))[3] = v10;
|
||||
viewData->_geometry->dirtyBound();
|
||||
|
||||
//OSG_NOTICE<<" new after RTT near ="<<cv->getCalculatedNearPlane()<<std::endl;
|
||||
//OSG_NOTICE<<" new after RTT far ="<<cv->getCalculatedFarPlane()<<std::endl;
|
||||
|
||||
viewData->_backdropSubgraph->accept(*cv);
|
||||
|
||||
osg::NodePath nodePathPriorToTraversingSubgraph = cv->getNodePath();
|
||||
cv->setUserValue("VolumeSceneTraversal",std::string("Post"));
|
||||
|
||||
// for each tile that needs post rendering we need to add it into current RenderStage.
|
||||
Tiles& tiles = viewData->_tiles;
|
||||
for(Tiles::iterator itr = tiles.begin();
|
||||
itr != tiles.end();
|
||||
++itr)
|
||||
{
|
||||
TileData* tileData = itr->get();
|
||||
unsigned int numStateSetPushed = 0;
|
||||
|
||||
// OSG_NOTICE<<"VolumeTile to add "<<tileData->projectionMatrix.get()<<", "<<tileData->modelviewMatrix.get()<<std::endl;
|
||||
|
||||
|
||||
osg::NodePath& nodePath = tileData->nodePath;
|
||||
|
||||
cv->getNodePath() = nodePath;
|
||||
cv->pushProjectionMatrix(tileData->projectionMatrix.get());
|
||||
cv->pushModelViewMatrix(tileData->modelviewMatrix.get(), osg::Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT);
|
||||
|
||||
|
||||
cv->pushStateSet(viewData->_stateset.get());
|
||||
++numStateSetPushed;
|
||||
|
||||
|
||||
osg::NodePath::iterator np_itr = nodePath.begin();
|
||||
|
||||
// skip over all nodes above VolumeScene as this will have already been traverse by CullVisitor
|
||||
while(np_itr!=nodePath.end() && (*np_itr)!=viewData->_rttCamera.get()) { ++np_itr; }
|
||||
if (np_itr!=nodePath.end()) ++np_itr;
|
||||
|
||||
// push the stateset on the nodes between this VolumeScene and the VolumeTile
|
||||
for(osg::NodePath::iterator ss_itr = np_itr;
|
||||
ss_itr != nodePath.end();
|
||||
++ss_itr)
|
||||
{
|
||||
if ((*ss_itr)->getStateSet())
|
||||
{
|
||||
numStateSetPushed++;
|
||||
cv->pushStateSet((*ss_itr)->getStateSet());
|
||||
// OSG_NOTICE<<" pushing StateSet"<<std::endl;
|
||||
}
|
||||
}
|
||||
cv->traverse(*(tileData->nodePath.back()));
|
||||
|
||||
// pop the StateSet's
|
||||
for(unsigned int i=0; i<numStateSetPushed; ++i)
|
||||
{
|
||||
cv->popStateSet();
|
||||
// OSG_NOTICE<<" popping StateSet"<<std::endl;
|
||||
}
|
||||
|
||||
cv->popModelViewMatrix();
|
||||
cv->popProjectionMatrix();
|
||||
}
|
||||
|
||||
cv->getNodePath() = nodePathPriorToTraversingSubgraph;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user