Added support for using shaders to render the RTT textures with depth

This commit is contained in:
Robert Osfield 2013-11-26 19:03:46 +00:00
parent 477951b924
commit 1b3290221c
3 changed files with 155 additions and 14 deletions

View File

@ -17,7 +17,8 @@
#include <osg/Group>
#include <osg/Texture2D>
#include <osgUtil/CullVisitor>
#include <osgVolume/Export>
#include <osgVolume/VolumeTile>
namespace osgVolume {
@ -35,6 +36,8 @@ class OSGVOLUME_EXPORT VolumeScene : public osg::Group
virtual void traverse(osg::NodeVisitor& nv);
void tileVisited(osg::NodeVisitor* nv, osgVolume::VolumeTile* tile);
protected:
virtual ~VolumeScene();
@ -48,6 +51,9 @@ class OSGVOLUME_EXPORT VolumeScene : public osg::Group
osg::ref_ptr<osg::Camera> _rttCamera;
osg::ref_ptr<osg::Camera> _postCamera;
osg::ref_ptr<osgUtil::RenderStage> _parentRenderStage;
typedef std::list< osg::NodePath > Tiles;
Tiles _tiles;
protected:
virtual ~ViewData() {}
};

View File

@ -13,6 +13,7 @@
#include <osgVolume/MultipassTechnique>
#include <osgVolume/VolumeTile>
#include <osgVolume/VolumeScene>
#include <osg/Geometry>
#include <osg/io_utils>
@ -77,6 +78,20 @@ 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)
{
OSG_NOTICE<<" parent path node "<<*itr<<" "<<(*itr)->className()<<std::endl;
osgVolume::VolumeScene* vs = dynamic_cast<osgVolume::VolumeScene*>(*itr);
if (vs)
{
OSG_NOTICE<<" HAVE VolumeScene"<<std::endl;
vs->tileVisited(cv, getVolumeTile());
break;
}
}
}
void MultipassTechnique::cleanSceneGraph()

View File

@ -14,6 +14,8 @@
#include <osgVolume/VolumeScene>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/io_utils>
#include <osgDB/ReadFile>
#include <OpenThreads/ScopedLock>
using namespace osgVolume;
@ -28,7 +30,21 @@ 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)
@ -70,6 +86,25 @@ VolumeScene::~VolumeScene()
{
}
void VolumeScene::tileVisited(osg::NodeVisitor* nv, osgVolume::VolumeTile* tile)
{
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
if (cv)
{
osg::ref_ptr<ViewData> viewData;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_viewDataMapMutex);
viewData = _viewDataMap[cv];
}
if (viewData.valid())
{
OSG_NOTICE<<"tileVisited("<<tile<<")"<<std::endl;
viewData->_tiles.push_back(nv->getNodePath());
}
}
}
void VolumeScene::traverse(osg::NodeVisitor& nv)
@ -77,9 +112,20 @@ void VolumeScene::traverse(osg::NodeVisitor& 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::ref_ptr<ViewData> viewData;
bool initializeViewData = false;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_viewDataMapMutex);
if (!_viewDataMap[cv])
{
_viewDataMap[cv] = new ViewData;
initializeViewData = true;
}
viewData = _viewDataMap[cv];
}
if (initializeViewData)
{
OSG_NOTICE<<"Creating ViewData"<<std::endl;
@ -87,7 +133,12 @@ void VolumeScene::traverse(osg::NodeVisitor& nv)
unsigned textureWidth = 512;
unsigned textureHeight = 512;
viewData = new ViewData;
osg::Viewport* viewport = cv->getCurrentRenderStage()->getViewport();
if (viewport)
{
textureWidth = viewport->width();
textureHeight = viewport->height();
}
// set up depth texture
viewData->_depthTexture = new osg::Texture2D;
@ -109,9 +160,8 @@ void VolumeScene::traverse(osg::NodeVisitor& nv)
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));
viewData->_colorTexture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_EDGE);
viewData->_colorTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_EDGE);
// set up the RTT Camera to capture the main scene to a color and depth texture that can be used in post processing
@ -127,8 +177,6 @@ void VolumeScene::traverse(osg::NodeVisitor& nv)
// 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);
@ -140,10 +188,45 @@ 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->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);
osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet();
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);
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
osg::ref_ptr<osg::Program> program = new osg::Program;
stateset->setAttribute(program);
// get vertex shaders from source
osg::ref_ptr<osg::Shader> vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, "shaders/volume_color_depth.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_color_depth.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
stateset->addUniform(new osg::Uniform("colorTexture",0));
stateset->addUniform(new osg::Uniform("depthTexture",1));
viewData->_postCamera = new osg::Camera;
viewData->_postCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
@ -156,11 +239,48 @@ void VolumeScene::traverse(osg::NodeVisitor& nv)
}
// 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)
{
if (viewport->width() != viewData->_colorTexture->getTextureWidth() ||
viewport->height() != viewData->_colorTexture->getTextureHeight())
{
OSG_NOTICE<<"Need to change texture size to "<<viewport->width()<<", "<< viewport->height()<<std::endl;
viewData->_colorTexture->setTextureSize(viewport->width(), viewport->height());
viewData->_colorTexture->dirtyTextureObject();
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);
}
}
}
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;
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<<" 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<<"Ready to traverse POST Camera"<<std::endl;
viewData->_postCamera->accept(nv);
}