Added initial render to texture functionality into osgVolume::VolumeScene

This commit is contained in:
Robert Osfield 2013-11-25 17:36:17 +00:00
parent f02ed3c629
commit 4fcf8d3e86
3 changed files with 160 additions and 1 deletions

View File

@ -49,6 +49,7 @@
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgUtil/CullVisitor>
@ -490,6 +491,9 @@ int main( int argc, char **argv )
// add the stats handler
viewer.addEventHandler(new osgViewer::StatsHandler);
// add stateset manipulator
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
viewer.getCamera()->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,0.0f));
// if user request help write it out to cout.
@ -1225,6 +1229,8 @@ int main( int argc, char **argv )
}
// set the scene to render
viewer.setSceneData(loadedModel.get());

View File

@ -15,6 +15,8 @@
#define OSGVOLUMESCENE 1
#include <osg/Group>
#include <osg/Texture2D>
#include <osgUtil/CullVisitor>
#include <osgVolume/Export>
namespace osgVolume {
@ -37,6 +39,22 @@ class OSGVOLUME_EXPORT VolumeScene : public osg::Group
virtual ~VolumeScene();
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;
protected:
virtual ~ViewData() {}
};
typedef std::map< osgUtil::CullVisitor*, osg::ref_ptr<ViewData> > ViewDataMap;
OpenThreads::Mutex _viewDataMapMutex;
ViewDataMap _viewDataMap;
};
}

View File

@ -12,10 +12,50 @@
*/
#include <osgVolume/VolumeScene>
#include <osg/Geometry>
#include <osg/Geode>
#include <OpenThreads/ScopedLock>
using namespace osgVolume;
class RTTCameraCullCallback : public osg::NodeCallback
{
public:
RTTCameraCullCallback(VolumeScene* vs):
_volumeScene(vs) {}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
#if 1
_volumeScene->osg::Group::traverse(*nv);
#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
}
protected:
virtual ~RTTCameraCullCallback() {}
osgVolume::VolumeScene* _volumeScene;
};
VolumeScene::ViewData::ViewData()
{
}
VolumeScene::VolumeScene()
{
}
@ -30,7 +70,102 @@ VolumeScene::~VolumeScene()
{
}
void VolumeScene::traverse(osg::NodeVisitor& nv)
{
Group::traverse(nv);
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
if (cv)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_viewDataMapMutex);
osg::ref_ptr<ViewData>& viewData = _viewDataMap[cv];
if (!viewData)
{
OSG_NOTICE<<"Creating ViewData"<<std::endl;
unsigned textureWidth = 512;
unsigned textureHeight = 512;
viewData = new ViewData;
// set up depth texture
viewData->_depthTexture = new osg::Texture2D;
viewData->_depthTexture->setTextureSize(textureWidth, textureHeight);
viewData->_depthTexture->setInternalFormat(GL_DEPTH_COMPONENT);
viewData->_depthTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
viewData->_depthTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
viewData->_depthTexture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
viewData->_depthTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
viewData->_depthTexture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
// set up color texture
viewData->_colorTexture = new osg::Texture2D;
viewData->_colorTexture->setTextureSize(textureWidth, textureHeight);
viewData->_colorTexture->setInternalFormat(GL_RGBA);
viewData->_colorTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
viewData->_colorTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
viewData->_colorTexture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
viewData->_colorTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
viewData->_colorTexture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
// set up the RTT Camera to capture the main scene to a color and depth texture that can be used in post processing
viewData->_rttCamera = new osg::Camera;
viewData->_rttCamera->attach(osg::Camera::DEPTH_BUFFER, viewData->_depthTexture.get());
viewData->_rttCamera->attach(osg::Camera::COLOR_BUFFER, viewData->_colorTexture.get());
viewData->_rttCamera->setCullCallback(new RTTCameraCullCallback(this));
viewData->_rttCamera->setViewport(0,0,textureWidth,textureHeight);
// clear the depth and colour bufferson each clear.
viewData->_rttCamera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
// set the camera to render before the main camera.
viewData->_rttCamera->setRenderOrder(osg::Camera::PRE_RENDER);
viewData->_rttCamera->setClearColor(osg::Vec4(1.0,0.5,0.5,1.0));
// tell the camera to use OpenGL frame buffer object where supported.
viewData->_rttCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
viewData->_rttCamera->setReferenceFrame(osg::Transform::RELATIVE_RF);
viewData->_rttCamera->setProjectionMatrix(osg::Matrixd::identity());
viewData->_rttCamera->setViewMatrix(osg::Matrixd::identity());
// 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->getOrCreateStateSet()->setTextureAttributeAndModes(0, viewData->_colorTexture.get(), osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, viewData->_depthTexture.get(), osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
viewData->_postCamera = new osg::Camera;
viewData->_postCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
viewData->_postCamera->addChild(geode);
}
else
{
OSG_NOTICE<<"Reusing ViewData"<<std::endl;
}
viewData->_parentRenderStage = cv->getCurrentRenderStage();
OSG_NOTICE<<"Ready to traverse RTT Camera"<<std::endl;
viewData->_rttCamera->accept(nv);
OSG_NOTICE<<"Ready to traverse POST Camera"<<std::endl;
viewData->_postCamera->accept(nv);
}
else
{
Group::traverse(nv);
}
}