Added support for using shaders to render the RTT textures with depth
This commit is contained in:
parent
477951b924
commit
1b3290221c
@ -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() {}
|
||||
};
|
||||
|
@ -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()
|
||||
|
@ -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,16 +86,46 @@ 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)
|
||||
{
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
|
||||
if (cv)
|
||||
{
|
||||
osg::ref_ptr<ViewData> viewData;
|
||||
bool initializeViewData = false;
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_viewDataMapMutex);
|
||||
osg::ref_ptr<ViewData>& viewData = _viewDataMap[cv];
|
||||
if (!viewData)
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user