Work on the RenderToTexture usage of the new osg::CameraNode. Both osghud
and osgprerender now ported across to osg::CameraNode.
This commit is contained in:
parent
868d381528
commit
71122ff38f
@ -22,6 +22,7 @@
|
||||
#include <osg/Projection>
|
||||
#include <osg/PolygonOffset>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/CameraNode>
|
||||
|
||||
#include <osgText/Text>
|
||||
|
||||
@ -36,17 +37,6 @@ osg::Node* createHUD()
|
||||
osg::StateSet* stateset = geode->getOrCreateStateSet();
|
||||
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
|
||||
|
||||
#if 0
|
||||
// to ensure the hud appears on top we can either use osg::Depth to force the
|
||||
// depth fragments to be placed at the front of the screen.
|
||||
stateset->setAttribute(new osg::Depth(osg::Depth::LESS,0.0,0.0001));
|
||||
#else
|
||||
// or disable depth test, and make sure that the hud is drawn after everything
|
||||
// else so that it always appears ontop.
|
||||
stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
|
||||
stateset->setRenderBinDetails(11,"RenderBin");
|
||||
#endif
|
||||
|
||||
osg::Vec3 position(150.0f,800.0f,0.0f);
|
||||
osg::Vec3 delta(0.0f,-120.0f,0.0f);
|
||||
|
||||
@ -146,6 +136,42 @@ osg::Node* createHUD()
|
||||
geode->addDrawable(geom);
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
osg::CameraNode* camera = new osg::CameraNode;
|
||||
|
||||
// set the projection matrix
|
||||
camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
|
||||
|
||||
// set the view matrix
|
||||
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||
camera->setViewMatrix(osg::Matrix::identity());
|
||||
|
||||
// only clear the depth buffer
|
||||
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// draw subgraph after main camera view.
|
||||
camera->setRenderOrder(osg::CameraNode::POST_RENDER);
|
||||
|
||||
camera->addChild(geode);
|
||||
|
||||
return camera;
|
||||
|
||||
#else
|
||||
|
||||
#if 0
|
||||
// to ensure the hud appears on top we can either use osg::Depth to force the
|
||||
// depth fragments to be placed at the front of the screen.
|
||||
stateset->setAttribute(new osg::Depth(osg::Depth::LESS,0.0,0.0001));
|
||||
#else
|
||||
// or disable depth test, and make sure that the hud is drawn after everything
|
||||
// else so that it always appears ontop.
|
||||
stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
|
||||
stateset->setRenderBinDetails(11,"RenderBin");
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// create the hud.
|
||||
osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
|
||||
modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||
@ -157,6 +183,7 @@ osg::Node* createHUD()
|
||||
projection->addChild(modelview_abs);
|
||||
|
||||
return projection;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -23,180 +23,186 @@
|
||||
|
||||
#include <osgProducer/Viewer>
|
||||
|
||||
class MyUpdateCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
#define USE_CAMERA_NODE
|
||||
|
||||
MyUpdateCallback(osg::Node* subgraph):
|
||||
_subgraph(subgraph) {}
|
||||
#ifndef USE_CAMERA_NODE
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
// traverse the subgraph to update any nodes.
|
||||
if (_subgraph.valid()) _subgraph->accept(*nv);
|
||||
class MyUpdateCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
|
||||
// must traverse the Node's subgraph
|
||||
traverse(node,nv);
|
||||
}
|
||||
MyUpdateCallback(osg::Node* subgraph):
|
||||
_subgraph(subgraph) {}
|
||||
|
||||
osg::ref_ptr<osg::Node> _subgraph;
|
||||
};
|
||||
|
||||
class MyCullCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
|
||||
MyCullCallback(osg::Node* subgraph,osg::Texture2D* texture):
|
||||
_subgraph(subgraph),
|
||||
_texture(texture),
|
||||
_localState(new osg::StateSet) {}
|
||||
|
||||
MyCullCallback(osg::Node* subgraph,osg::Image* image):
|
||||
_subgraph(subgraph),
|
||||
_image(image),
|
||||
_localState(new osg::StateSet) {}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
|
||||
osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
|
||||
if (cullVisitor && (_texture.valid()|| _image.valid()) && _subgraph.valid())
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
doPreRender(*node,*cullVisitor);
|
||||
// traverse the subgraph to update any nodes.
|
||||
if (_subgraph.valid()) _subgraph->accept(*nv);
|
||||
|
||||
// must traverse the subgraph
|
||||
traverse(node,nv);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// must traverse the subgraph
|
||||
// must traverse the Node's subgraph
|
||||
traverse(node,nv);
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> _subgraph;
|
||||
};
|
||||
|
||||
|
||||
class MyCullCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
|
||||
MyCullCallback(osg::Node* subgraph,osg::Texture2D* texture):
|
||||
_subgraph(subgraph),
|
||||
_texture(texture),
|
||||
_localState(new osg::StateSet) {}
|
||||
|
||||
MyCullCallback(osg::Node* subgraph,osg::Image* image):
|
||||
_subgraph(subgraph),
|
||||
_image(image),
|
||||
_localState(new osg::StateSet) {}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
|
||||
osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
|
||||
if (cullVisitor && (_texture.valid()|| _image.valid()) && _subgraph.valid())
|
||||
{
|
||||
doPreRender(*node,*cullVisitor);
|
||||
|
||||
// must traverse the subgraph
|
||||
traverse(node,nv);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// must traverse the subgraph
|
||||
traverse(node,nv);
|
||||
}
|
||||
}
|
||||
|
||||
void doPreRender(osg::Node& node, osgUtil::CullVisitor& cv);
|
||||
|
||||
osg::ref_ptr<osg::Node> _subgraph;
|
||||
osg::ref_ptr<osg::Texture2D> _texture;
|
||||
osg::ref_ptr<osg::Image> _image;
|
||||
osg::ref_ptr<osg::StateSet> _localState;
|
||||
|
||||
};
|
||||
|
||||
void MyCullCallback::doPreRender(osg::Node&, osgUtil::CullVisitor& cv)
|
||||
{
|
||||
const osg::BoundingSphere& bs = _subgraph->getBound();
|
||||
if (!bs.valid())
|
||||
{
|
||||
osg::notify(osg::WARN) << "bb invalid"<<_subgraph.get()<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
void doPreRender(osg::Node& node, osgUtil::CullVisitor& cv);
|
||||
|
||||
osg::ref_ptr<osg::Node> _subgraph;
|
||||
osg::ref_ptr<osg::Texture2D> _texture;
|
||||
osg::ref_ptr<osg::Image> _image;
|
||||
osg::ref_ptr<osg::StateSet> _localState;
|
||||
// create the render to texture stage.
|
||||
osg::ref_ptr<osgUtil::RenderToTextureStage> rtts = new osgUtil::RenderToTextureStage;
|
||||
|
||||
};
|
||||
// set up lighting.
|
||||
// currently ignore lights in the scene graph itself..
|
||||
// will do later.
|
||||
osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage();
|
||||
|
||||
void MyCullCallback::doPreRender(osg::Node&, osgUtil::CullVisitor& cv)
|
||||
{
|
||||
const osg::BoundingSphere& bs = _subgraph->getBound();
|
||||
if (!bs.valid())
|
||||
{
|
||||
osg::notify(osg::WARN) << "bb invalid"<<_subgraph.get()<<std::endl;
|
||||
return;
|
||||
}
|
||||
// set up the background color and clear mask.
|
||||
rtts->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f));
|
||||
rtts->setClearMask(previous_stage->getClearMask());
|
||||
|
||||
// set up to charge the same RenderStageLighting is the parent previous stage.
|
||||
rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());
|
||||
|
||||
|
||||
// create the render to texture stage.
|
||||
osg::ref_ptr<osgUtil::RenderToTextureStage> rtts = new osgUtil::RenderToTextureStage;
|
||||
// record the render bin, to be restored after creation
|
||||
// of the render to text
|
||||
osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin();
|
||||
|
||||
// set up lighting.
|
||||
// currently ignore lights in the scene graph itself..
|
||||
// will do later.
|
||||
osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage();
|
||||
|
||||
// set up the background color and clear mask.
|
||||
rtts->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f));
|
||||
rtts->setClearMask(previous_stage->getClearMask());
|
||||
|
||||
// set up to charge the same RenderStageLighting is the parent previous stage.
|
||||
rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());
|
||||
// set the current renderbin to be the newly created stage.
|
||||
cv.setCurrentRenderBin(rtts.get());
|
||||
|
||||
|
||||
// record the render bin, to be restored after creation
|
||||
// of the render to text
|
||||
osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin();
|
||||
float znear = 1.0f*bs.radius();
|
||||
float zfar = 3.0f*bs.radius();
|
||||
|
||||
// set the current renderbin to be the newly created stage.
|
||||
cv.setCurrentRenderBin(rtts.get());
|
||||
// 2:1 aspect ratio as per flag geomtry below.
|
||||
float top = 0.25f*znear;
|
||||
float right = 0.5f*znear;
|
||||
|
||||
znear *= 0.9f;
|
||||
zfar *= 1.1f;
|
||||
|
||||
// set up projection.
|
||||
osg::RefMatrix* projection = new osg::RefMatrix;
|
||||
projection->makeFrustum(-right,right,-top,top,znear,zfar);
|
||||
|
||||
cv.pushProjectionMatrix(projection);
|
||||
|
||||
osg::RefMatrix* matrix = new osg::RefMatrix;
|
||||
matrix->makeLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));
|
||||
|
||||
cv.pushModelViewMatrix(matrix);
|
||||
|
||||
cv.pushStateSet(_localState.get());
|
||||
|
||||
{
|
||||
|
||||
// traverse the subgraph
|
||||
_subgraph->accept(cv);
|
||||
|
||||
}
|
||||
|
||||
cv.popStateSet();
|
||||
|
||||
// restore the previous model view matrix.
|
||||
cv.popModelViewMatrix();
|
||||
|
||||
// restore the previous model view matrix.
|
||||
cv.popProjectionMatrix();
|
||||
|
||||
// restore the previous renderbin.
|
||||
cv.setCurrentRenderBin(previousRenderBin);
|
||||
|
||||
if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0)
|
||||
{
|
||||
// getting to this point means that all the subgraph has been
|
||||
// culled by small feature culling or is beyond LOD ranges.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
float znear = 1.0f*bs.radius();
|
||||
float zfar = 3.0f*bs.radius();
|
||||
|
||||
// 2:1 aspect ratio as per flag geomtry below.
|
||||
float top = 0.25f*znear;
|
||||
float right = 0.5f*znear;
|
||||
int height = 256;
|
||||
int width = 512;
|
||||
|
||||
znear *= 0.9f;
|
||||
zfar *= 1.1f;
|
||||
|
||||
// set up projection.
|
||||
osg::RefMatrix* projection = new osg::RefMatrix;
|
||||
projection->makeFrustum(-right,right,-top,top,znear,zfar);
|
||||
const osg::Viewport& viewport = *cv.getViewport();
|
||||
|
||||
cv.pushProjectionMatrix(projection);
|
||||
// offset the impostor viewport from the center of the main window
|
||||
// viewport as often the edges of the viewport might be obscured by
|
||||
// other windows, which can cause image/reading writing problems.
|
||||
int center_x = viewport.x()+viewport.width()/2;
|
||||
int center_y = viewport.y()+viewport.height()/2;
|
||||
|
||||
osg::RefMatrix* matrix = new osg::RefMatrix;
|
||||
matrix->makeLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));
|
||||
osg::Viewport* new_viewport = new osg::Viewport;
|
||||
new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height);
|
||||
rtts->setViewport(new_viewport);
|
||||
|
||||
cv.pushModelViewMatrix(matrix);
|
||||
_localState->setAttribute(new_viewport);
|
||||
|
||||
cv.pushStateSet(_localState.get());
|
||||
// and the render to texture stage to the current stages
|
||||
// dependancy list.
|
||||
cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get());
|
||||
|
||||
{
|
||||
// if one exist attach texture to the RenderToTextureStage.
|
||||
if (_texture.valid()) rtts->setTexture(_texture.get());
|
||||
|
||||
// traverse the subgraph
|
||||
_subgraph->accept(cv);
|
||||
// if one exist attach image to the RenderToTextureStage.
|
||||
if (_image.valid()) rtts->setImage(_image.get());
|
||||
|
||||
}
|
||||
|
||||
cv.popStateSet();
|
||||
|
||||
// restore the previous model view matrix.
|
||||
cv.popModelViewMatrix();
|
||||
|
||||
// restore the previous model view matrix.
|
||||
cv.popProjectionMatrix();
|
||||
|
||||
// restore the previous renderbin.
|
||||
cv.setCurrentRenderBin(previousRenderBin);
|
||||
|
||||
if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0)
|
||||
{
|
||||
// getting to this point means that all the subgraph has been
|
||||
// culled by small feature culling or is beyond LOD ranges.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int height = 256;
|
||||
int width = 512;
|
||||
|
||||
|
||||
const osg::Viewport& viewport = *cv.getViewport();
|
||||
|
||||
// offset the impostor viewport from the center of the main window
|
||||
// viewport as often the edges of the viewport might be obscured by
|
||||
// other windows, which can cause image/reading writing problems.
|
||||
int center_x = viewport.x()+viewport.width()/2;
|
||||
int center_y = viewport.y()+viewport.height()/2;
|
||||
|
||||
osg::Viewport* new_viewport = new osg::Viewport;
|
||||
new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height);
|
||||
rtts->setViewport(new_viewport);
|
||||
|
||||
_localState->setAttribute(new_viewport);
|
||||
|
||||
// and the render to texture stage to the current stages
|
||||
// dependancy list.
|
||||
cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get());
|
||||
|
||||
// if one exist attach texture to the RenderToTextureStage.
|
||||
if (_texture.valid()) rtts->setTexture(_texture.get());
|
||||
|
||||
// if one exist attach image to the RenderToTextureStage.
|
||||
if (_image.valid()) rtts->setImage(_image.get());
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
// call back which cretes a deformation field to oscilate the model.
|
||||
class MyGeometryCallback :
|
||||
@ -352,6 +358,8 @@ osg::Node* createPreRenderSubGraph(osg::Node* subgraph)
|
||||
osg::Geode* geode = new osg::Geode();
|
||||
geode->addDrawable(polyGeom);
|
||||
|
||||
#ifndef USE_CAMERA_NODE
|
||||
|
||||
osg::Group* parent = new osg::Group;
|
||||
|
||||
parent->setUpdateCallback(new MyUpdateCallback(subgraph));
|
||||
@ -361,6 +369,63 @@ osg::Node* createPreRenderSubGraph(osg::Node* subgraph)
|
||||
parent->addChild(geode);
|
||||
|
||||
return parent;
|
||||
|
||||
#else
|
||||
|
||||
|
||||
osg::CameraNode* camera = new osg::CameraNode;
|
||||
|
||||
// set up the background color and clear mask.
|
||||
camera->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f));
|
||||
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
const osg::BoundingSphere& bs = subgraph->getBound();
|
||||
if (!bs.valid())
|
||||
{
|
||||
return subgraph;
|
||||
}
|
||||
|
||||
float znear = 1.0f*bs.radius();
|
||||
float zfar = 3.0f*bs.radius();
|
||||
|
||||
// 2:1 aspect ratio as per flag geomtry below.
|
||||
float proj_top = 0.25f*znear;
|
||||
float proj_right = 0.5f*znear;
|
||||
|
||||
znear *= 0.9f;
|
||||
zfar *= 1.1f;
|
||||
|
||||
// set up projection.
|
||||
camera->setProjectionMatrixAsFrustum(-proj_right,proj_right,-proj_top,proj_top,znear,zfar);
|
||||
|
||||
// set view
|
||||
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||
camera->setViewMatrixAsLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));
|
||||
|
||||
// set viewport
|
||||
camera->setViewport(0,0,1024,512);
|
||||
|
||||
camera->getOrCreateStateSet()->setAttribute(camera->getViewport());
|
||||
|
||||
// set the camera to render before the main camera.
|
||||
camera->setRenderOrder(osg::CameraNode::PRE_RENDER);
|
||||
|
||||
camera->attach(osg::CameraNode::COLOR_BUFFER,texture);
|
||||
|
||||
// add subgraph to render
|
||||
camera->addChild(subgraph);
|
||||
|
||||
|
||||
// create a group to contain the flag and the pre rendering camera.
|
||||
osg::Group* parent = new osg::Group;
|
||||
|
||||
parent->addChild(camera);
|
||||
parent->addChild(geode);
|
||||
|
||||
|
||||
return parent;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
|
@ -16,12 +16,15 @@
|
||||
|
||||
#include <osg/Transform>
|
||||
#include <osg/Viewport>
|
||||
#include <osg/CullSettings>
|
||||
#include <osg/Texture>
|
||||
#include <osg/Image>
|
||||
|
||||
namespace osg {
|
||||
|
||||
/** CameraNode - is a subclass of Transform which represents encapsulates the settings of a Camera.
|
||||
*/
|
||||
class OSG_EXPORT CameraNode : public Transform
|
||||
class OSG_EXPORT CameraNode : public Transform, public CullSettings
|
||||
{
|
||||
public :
|
||||
|
||||
@ -34,20 +37,6 @@ class OSG_EXPORT CameraNode : public Transform
|
||||
META_Node(osg, CameraNode);
|
||||
|
||||
|
||||
/** Sets the clear color. */
|
||||
inline void setClearColor(const Vec4& color) { _clearColor = color; }
|
||||
|
||||
/** Returns the clear color. */
|
||||
inline const Vec4& getClearColor() const { return _clearColor; }
|
||||
|
||||
/** Set the clear mask used in glClear(..).
|
||||
* Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */
|
||||
inline void setClearMask(GLbitfield mask) { _clearMask = mask; }
|
||||
|
||||
/** Get the clear mask.*/
|
||||
inline GLbitfield getClearMask() const { return _clearMask; }
|
||||
|
||||
|
||||
|
||||
/** Set the viewport of the scene view to use specified osg::Viewport. */
|
||||
void setViewport(osg::Viewport* viewport)
|
||||
@ -151,7 +140,76 @@ class OSG_EXPORT CameraNode : public Transform
|
||||
|
||||
|
||||
|
||||
/** Sets the clear color. */
|
||||
inline void setClearColor(const Vec4& color) { _clearColor = color; }
|
||||
|
||||
/** Returns the clear color. */
|
||||
inline const Vec4& getClearColor() const { return _clearColor; }
|
||||
|
||||
/** Set the clear mask used in glClear(..).
|
||||
* Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */
|
||||
inline void setClearMask(GLbitfield mask) { _clearMask = mask; }
|
||||
|
||||
/** Get the clear mask.*/
|
||||
inline GLbitfield getClearMask() const { return _clearMask; }
|
||||
|
||||
|
||||
|
||||
enum RenderOrder
|
||||
{
|
||||
PRE_RENDER,
|
||||
NESTED_RENDER,
|
||||
POST_RENDER
|
||||
};
|
||||
|
||||
/** Set the rendering order of this camera's subgraph relative to any camera that this subgraph is nested within.
|
||||
* For rendering to a texture, one typically uses PRE_RENDER.
|
||||
* For Head Up Displays, one would typically use POST_RENDER.*/
|
||||
void setRenderOrder(RenderOrder order) { _renderOrder = order; }
|
||||
|
||||
/** Get the rendering order of this camera's subgraph relative to any camera that this subgraph is nested within.*/
|
||||
RenderOrder getRenderOrder() const { return _renderOrder; }
|
||||
|
||||
enum RenderTargetImplementation
|
||||
{
|
||||
FRAME_BUFFER_OBJECT,
|
||||
PIXEL_BUFFER,
|
||||
FRAME_BUFFER
|
||||
};
|
||||
|
||||
void setRenderTargetImplmentation(RenderTargetImplementation impl) { _renderTargetImplementation = impl; }
|
||||
RenderTargetImplementation getRenderTargetImplmentation() const { return _renderTargetImplementation; }
|
||||
|
||||
enum BufferComponent
|
||||
{
|
||||
COLOR_BUFFER,
|
||||
DEPTH_BUFFER,
|
||||
STENCIL_BUFFER
|
||||
};
|
||||
|
||||
void attach(BufferComponent buffer, GLenum internalFormat);
|
||||
|
||||
void attach(BufferComponent buffer, osg::Texture* texture, unsigned int face=0);
|
||||
|
||||
void attach(BufferComponent buffer, osg::Image* image);
|
||||
|
||||
void detach(BufferComponent buffer);
|
||||
|
||||
struct Attachment
|
||||
{
|
||||
GLenum _internalFormat;
|
||||
ref_ptr<Image> _image;
|
||||
ref_ptr<Texture> _texture;
|
||||
unsigned int _face;
|
||||
};
|
||||
|
||||
typedef std::map< BufferComponent, Attachment> BufferAttachmentMap;
|
||||
|
||||
BufferAttachmentMap& getBufferAttachmentMap() { return _bufferAttachmentMap; }
|
||||
const BufferAttachmentMap& getBufferAttachmentMap() const { return _bufferAttachmentMap; }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/** Transform method that must be defined to provide generic interface for scene graph traversals.*/
|
||||
@ -164,11 +222,16 @@ class OSG_EXPORT CameraNode : public Transform
|
||||
|
||||
virtual ~CameraNode();
|
||||
|
||||
Vec4 _clearColor;
|
||||
GLbitfield _clearMask;
|
||||
ref_ptr<Viewport> _viewport;
|
||||
Matrixd _projectionMatrix;
|
||||
Matrixd _viewMatrix;
|
||||
Vec4 _clearColor;
|
||||
GLbitfield _clearMask;
|
||||
ref_ptr<Viewport> _viewport;
|
||||
Matrixd _projectionMatrix;
|
||||
Matrixd _viewMatrix;
|
||||
|
||||
RenderOrder _renderOrder;
|
||||
|
||||
RenderTargetImplementation _renderTargetImplementation;
|
||||
BufferAttachmentMap _bufferAttachmentMap;
|
||||
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <osg/StateSet>
|
||||
#include <osg/State>
|
||||
#include <osg/ClearNode>
|
||||
#include <osg/CameraNode>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osg/CullStack>
|
||||
@ -75,6 +76,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac
|
||||
virtual void apply(osg::Switch& node);
|
||||
virtual void apply(osg::LOD& node);
|
||||
virtual void apply(osg::ClearNode& node);
|
||||
virtual void apply(osg::CameraNode& node);
|
||||
virtual void apply(osg::OccluderNode& node);
|
||||
|
||||
void setClearNode(const osg::ClearNode* earthSky) { _clearNode = earthSky; }
|
||||
|
@ -127,9 +127,14 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
|
||||
|
||||
virtual void draw(osg::State& state,RenderLeaf*& previous);
|
||||
|
||||
virtual void drawPostRenderStages(osg::State& state,RenderLeaf*& previous);
|
||||
|
||||
virtual void drawImplementation(osg::State& state,RenderLeaf*& previous);
|
||||
|
||||
void addToDependencyList(RenderStage* rs);
|
||||
void addToDependencyList(RenderStage* rs) { addPreRenderStage(rs); }
|
||||
|
||||
void addPreRenderStage(RenderStage* rs);
|
||||
void addPostRenderStage(RenderStage* rs);
|
||||
|
||||
/** Extract stats for current draw list. */
|
||||
bool getStats(Statistics* primStats);
|
||||
@ -138,10 +143,11 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
|
||||
|
||||
virtual ~RenderStage();
|
||||
|
||||
typedef std::vector< osg::ref_ptr<RenderStage> > DependencyList;
|
||||
typedef std::vector< osg::ref_ptr<RenderStage> > RenderStageList;
|
||||
|
||||
bool _stageDrawnThisFrame;
|
||||
DependencyList _dependencyList;
|
||||
RenderStageList _preRenderList;
|
||||
RenderStageList _postRenderList;
|
||||
|
||||
// viewport x,y,width,height.
|
||||
osg::ref_ptr<osg::Viewport> _viewport;
|
||||
|
@ -18,17 +18,24 @@ using namespace osg;
|
||||
|
||||
CameraNode::CameraNode():
|
||||
_clearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)),
|
||||
_clearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||
_clearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT),
|
||||
_renderOrder(POST_RENDER),
|
||||
_renderTargetImplementation(FRAME_BUFFER)
|
||||
{
|
||||
}
|
||||
|
||||
CameraNode::CameraNode(const CameraNode& camera,const CopyOp& copyop):
|
||||
Transform(camera,copyop),
|
||||
CullSettings(camera),
|
||||
_clearColor(camera._clearColor),
|
||||
_clearMask(camera._clearMask),
|
||||
_viewport(camera._viewport),
|
||||
_projectionMatrix(camera._projectionMatrix),
|
||||
_viewMatrix(camera._viewMatrix)
|
||||
_viewMatrix(camera._viewMatrix),
|
||||
_renderOrder(camera._renderOrder),
|
||||
_renderTargetImplementation(camera._renderTargetImplementation),
|
||||
_bufferAttachmentMap(camera._bufferAttachmentMap)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
@ -109,6 +116,29 @@ void CameraNode::getViewMatrixAsLookAt(Vec3& eye,Vec3& center,Vec3& up,float loo
|
||||
_viewMatrix.getLookAt(eye,center,up,lookDistance);
|
||||
}
|
||||
|
||||
|
||||
void CameraNode::attach(BufferComponent buffer, GLenum internalFormat)
|
||||
{
|
||||
_bufferAttachmentMap[buffer]._internalFormat = internalFormat;
|
||||
}
|
||||
|
||||
void CameraNode::attach(BufferComponent buffer, osg::Texture* texture, unsigned int face)
|
||||
{
|
||||
_bufferAttachmentMap[buffer]._texture = texture;
|
||||
_bufferAttachmentMap[buffer]._face = face;
|
||||
}
|
||||
|
||||
void CameraNode::attach(BufferComponent buffer, osg::Image* image)
|
||||
{
|
||||
_bufferAttachmentMap[buffer]._image = image;
|
||||
}
|
||||
|
||||
void CameraNode::detach(BufferComponent buffer)
|
||||
{
|
||||
_bufferAttachmentMap.erase(buffer);
|
||||
}
|
||||
|
||||
|
||||
bool CameraNode::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const
|
||||
{
|
||||
if (_referenceFrame==RELATIVE_RF)
|
||||
|
@ -1023,6 +1023,100 @@ void CullVisitor::apply(osg::ClearNode& node)
|
||||
|
||||
}
|
||||
|
||||
void CullVisitor::apply(osg::CameraNode& camera)
|
||||
{
|
||||
// push the node's state.
|
||||
StateSet* node_state = camera.getStateSet();
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
// use render to texture stage.
|
||||
{
|
||||
// create the render to texture stage.
|
||||
osg::ref_ptr<osgUtil::RenderToTextureStage> rtts = new osgUtil::RenderToTextureStage;
|
||||
|
||||
// set up lighting.
|
||||
// currently ignore lights in the scene graph itself..
|
||||
// will do later.
|
||||
osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage();
|
||||
|
||||
// set up the background color and clear mask.
|
||||
rtts->setClearColor(camera.getClearColor());
|
||||
rtts->setClearMask(camera.getClearMask());
|
||||
|
||||
// set up the viewport.
|
||||
rtts->setViewport( camera.getViewport()!=0 ? camera.getViewport() : previous_stage->getViewport());
|
||||
|
||||
// set up to charge the same RenderStageLighting is the parent previous stage.
|
||||
rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());
|
||||
|
||||
// record the render bin, to be restored after creation
|
||||
// of the render to text
|
||||
osgUtil::RenderBin* previousRenderBin = getCurrentRenderBin();
|
||||
|
||||
// set the current renderbin to be the newly created stage.
|
||||
setCurrentRenderBin(rtts.get());
|
||||
|
||||
pushProjectionMatrix(new osg::RefMatrix(camera.getProjectionMatrix()));
|
||||
|
||||
pushModelViewMatrix(new osg::RefMatrix(camera.getViewMatrix()));
|
||||
|
||||
// traverse the subgraph
|
||||
{
|
||||
handle_cull_callbacks_and_traverse(camera);
|
||||
}
|
||||
|
||||
// restore the previous model view matrix.
|
||||
popModelViewMatrix();
|
||||
|
||||
// restore the previous model view matrix.
|
||||
popProjectionMatrix();
|
||||
|
||||
// restore the previous renderbin.
|
||||
setCurrentRenderBin(previousRenderBin);
|
||||
|
||||
if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0)
|
||||
{
|
||||
// getting to this point means that all the subgraph has been
|
||||
// culled by small feature culling or is beyond LOD ranges.
|
||||
}
|
||||
|
||||
|
||||
// and the render to texture stage to the current stages
|
||||
// dependancy list.
|
||||
switch(camera.getRenderOrder())
|
||||
{
|
||||
case osg::CameraNode::PRE_RENDER :
|
||||
getCurrentRenderBin()->getStage()->addPreRenderStage(rtts.get());
|
||||
break;
|
||||
case osg::CameraNode::NESTED_RENDER :
|
||||
getCurrentRenderBin()->getStage()->addPostRenderStage(rtts.get());
|
||||
break;
|
||||
case osg::CameraNode::POST_RENDER :
|
||||
getCurrentRenderBin()->getStage()->addPostRenderStage(rtts.get());
|
||||
break;
|
||||
}
|
||||
|
||||
osg::CameraNode::BufferAttachmentMap& bufferAttachements = camera.getBufferAttachmentMap();
|
||||
for(osg::CameraNode::BufferAttachmentMap::iterator itr = bufferAttachements.begin();
|
||||
itr != bufferAttachements.end();
|
||||
++itr)
|
||||
{
|
||||
|
||||
// if one exist attach texture to the RenderToTextureStage.
|
||||
osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(itr->second._texture.get());
|
||||
if (texture2D) rtts->setTexture(texture2D);
|
||||
|
||||
// if one exist attach image to the RenderToTextureStage.
|
||||
if (itr->second._image.valid()) rtts->setImage(itr->second._image.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// pop the node's state off the render graph stack.
|
||||
if (node_state) popStateSet();
|
||||
|
||||
}
|
||||
|
||||
void CullVisitor::apply(osg::OccluderNode& node)
|
||||
{
|
||||
// need to check if occlusion node is in the occluder
|
||||
|
@ -322,7 +322,7 @@ RenderBin* RenderBin::find_or_insert(int binNum,const std::string& binName)
|
||||
rs->_binNum = binNum;
|
||||
rs->_parent = NULL;
|
||||
rs->_stage = rs;
|
||||
_stage->addToDependencyList(rs);
|
||||
_stage->addPreRenderStage(rs);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -56,7 +56,8 @@ RenderStage::RenderStage(SortMode mode):
|
||||
RenderStage::RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop):
|
||||
RenderBin(rhs,copyop),
|
||||
_stageDrawnThisFrame(false),
|
||||
_dependencyList(rhs._dependencyList),
|
||||
_preRenderList(rhs._preRenderList),
|
||||
_postRenderList(rhs._postRenderList),
|
||||
_viewport(rhs._viewport),
|
||||
_clearMask(rhs._clearMask),
|
||||
_colorMask(rhs._colorMask),
|
||||
@ -77,7 +78,7 @@ RenderStage::~RenderStage()
|
||||
|
||||
void RenderStage::reset()
|
||||
{
|
||||
_dependencyList.clear();
|
||||
_preRenderList.clear();
|
||||
_stageDrawnThisFrame = false;
|
||||
|
||||
if (_renderStageLighting.valid()) _renderStageLighting->reset();
|
||||
@ -85,18 +86,23 @@ void RenderStage::reset()
|
||||
RenderBin::reset();
|
||||
}
|
||||
|
||||
void RenderStage::addToDependencyList(RenderStage* rs)
|
||||
void RenderStage::addPreRenderStage(RenderStage* rs)
|
||||
{
|
||||
if (rs) _dependencyList.push_back(rs);
|
||||
if (rs) _preRenderList.push_back(rs);
|
||||
}
|
||||
|
||||
void RenderStage::addPostRenderStage(RenderStage* rs)
|
||||
{
|
||||
if (rs) _postRenderList.push_back(rs);
|
||||
}
|
||||
|
||||
void RenderStage::drawPreRenderStages(osg::State& state,RenderLeaf*& previous)
|
||||
{
|
||||
if (_dependencyList.empty()) return;
|
||||
if (_preRenderList.empty()) return;
|
||||
|
||||
//cout << "Drawing prerendering stages "<<this<< " "<<_viewport->x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<<std::endl;
|
||||
for(DependencyList::iterator itr=_dependencyList.begin();
|
||||
itr!=_dependencyList.end();
|
||||
for(RenderStageList::iterator itr=_preRenderList.begin();
|
||||
itr!=_preRenderList.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->draw(state,previous);
|
||||
@ -115,6 +121,10 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
|
||||
//drawPreRenderStages(state,previous);
|
||||
|
||||
RenderBin::draw(state,previous);
|
||||
|
||||
// place the post draw here temprorarily while we figure out how
|
||||
// best to do SceneView.
|
||||
drawPostRenderStages(state,previous);
|
||||
}
|
||||
|
||||
void RenderStage::drawImplementation(osg::State& state,RenderLeaf*& previous)
|
||||
@ -182,6 +192,21 @@ void RenderStage::drawImplementation(osg::State& state,RenderLeaf*& previous)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RenderStage::drawPostRenderStages(osg::State& state,RenderLeaf*& previous)
|
||||
{
|
||||
if (_postRenderList.empty()) return;
|
||||
|
||||
//cout << "Drawing prerendering stages "<<this<< " "<<_viewport->x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<<std::endl;
|
||||
for(RenderStageList::iterator itr=_postRenderList.begin();
|
||||
itr!=_postRenderList.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->draw(state,previous);
|
||||
}
|
||||
//cout << "Done Drawing prerendering stages "<<this<< " "<<_viewport->x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<<std::endl;
|
||||
}
|
||||
|
||||
// Statistics features
|
||||
bool RenderStage::getStats(Statistics* primStats)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user