Added multi-buffering of the CameraNode::_renderingCache to help cope with multiple graphis context usages.
This commit is contained in:
@@ -22,6 +22,8 @@
|
||||
#include <osg/Image>
|
||||
#include <osg/GraphicsContext>
|
||||
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
namespace osg {
|
||||
|
||||
/** CameraNode - is a subclass of Transform which represents encapsulates the settings of a Camera.
|
||||
@@ -273,13 +275,13 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings
|
||||
|
||||
|
||||
/** Set the Rendering object that is used to implement rendering of the subgraph.*/
|
||||
void setRenderingCache(osg::Object* rc) { _renderingCache = rc; }
|
||||
void setRenderingCache(unsigned int contextID, osg::Object* rc) { _renderingCache[contextID] = rc; }
|
||||
|
||||
/** Get the Rendering object that is used to implement rendering of the subgraph.*/
|
||||
osg::Object* getRenderingCache() { return _renderingCache.get(); }
|
||||
osg::Object* getRenderingCache(unsigned int contextID) { return _renderingCache[contextID].get(); }
|
||||
|
||||
/** Get the const Rendering object that is used to implement rendering of the subgraph.*/
|
||||
const osg::Object* getRenderingCache() const { return _renderingCache.get(); }
|
||||
const osg::Object* getRenderingCache(unsigned int contextID) const { return _renderingCache[contextID].get(); }
|
||||
|
||||
|
||||
/** Draw callback for custom operations.*/
|
||||
@@ -303,6 +305,7 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings
|
||||
/** Get the const post draw callback.*/
|
||||
const DrawCallback* getPostDrawCallback() const { return _postDrawCallback.get(); }
|
||||
|
||||
OpenThreads::Mutex& getDataChangeMutex() const { return _dataChangeMutex; }
|
||||
|
||||
public:
|
||||
|
||||
@@ -315,6 +318,8 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings
|
||||
protected :
|
||||
|
||||
virtual ~CameraNode();
|
||||
|
||||
mutable OpenThreads::Mutex _dataChangeMutex;
|
||||
|
||||
Vec4 _clearColor;
|
||||
GLbitfield _clearMask;
|
||||
@@ -334,10 +339,10 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings
|
||||
RenderTargetImplementation _renderTargetFallback;
|
||||
BufferAttachmentMap _bufferAttachmentMap;
|
||||
|
||||
ref_ptr<GraphicsContext> _graphicsContext;
|
||||
ref_ptr<Object> _renderingCache;
|
||||
ref_ptr<GraphicsContext> _graphicsContext;
|
||||
buffered_object< ref_ptr<Object> > _renderingCache;
|
||||
|
||||
ref_ptr<DrawCallback> _postDrawCallback;
|
||||
ref_ptr<DrawCallback> _postDrawCallback;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -404,9 +404,6 @@ void FrameBufferObject::apply(State &state) const
|
||||
return;
|
||||
|
||||
|
||||
|
||||
state.checkGLErrors("A");
|
||||
|
||||
FBOExtensions* ext = FBOExtensions::instance(contextID);
|
||||
if (!ext->isSupported())
|
||||
{
|
||||
@@ -421,8 +418,6 @@ void FrameBufferObject::apply(State &state) const
|
||||
return;
|
||||
}
|
||||
|
||||
state.checkGLErrors("B");
|
||||
|
||||
int &dirtyAttachmentList = _dirtyAttachmentList[contextID];
|
||||
|
||||
GLuint &fboID = _fboID[contextID];
|
||||
@@ -439,10 +434,16 @@ void FrameBufferObject::apply(State &state) const
|
||||
|
||||
}
|
||||
|
||||
state.checkGLErrors("C");
|
||||
|
||||
if (dirtyAttachmentList)
|
||||
{
|
||||
// the set of of attachements appears to be thread sensitive, it shouldn't be because
|
||||
// OpenGL FBO handles osg::FrameBufferObject has are multi-buffered...
|
||||
// so as a temporary fix will stick in a mutex to ensure that only one thread passes through here
|
||||
// at one time.
|
||||
static OpenThreads::Mutex s_mutex;
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex);
|
||||
|
||||
|
||||
// create textures and mipmaps before we bind the frame buffer object
|
||||
for (AttachmentMap::const_iterator i=_attachments.begin(); i!=_attachments.end(); ++i)
|
||||
{
|
||||
@@ -452,12 +453,8 @@ void FrameBufferObject::apply(State &state) const
|
||||
|
||||
}
|
||||
|
||||
state.checkGLErrors("D");
|
||||
|
||||
ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
|
||||
|
||||
state.checkGLErrors("E");
|
||||
|
||||
if (dirtyAttachmentList)
|
||||
{
|
||||
for (AttachmentMap::const_iterator i=_attachments.begin(); i!=_attachments.end(); ++i)
|
||||
@@ -467,7 +464,7 @@ void FrameBufferObject::apply(State &state) const
|
||||
}
|
||||
dirtyAttachmentList = 0;
|
||||
}
|
||||
state.checkGLErrors("F");
|
||||
|
||||
}
|
||||
|
||||
int FrameBufferObject::compare(const StateAttribute &sa) const
|
||||
|
||||
@@ -1097,12 +1097,15 @@ void CullVisitor::apply(osg::CameraNode& camera)
|
||||
// will do later.
|
||||
osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage();
|
||||
|
||||
unsigned int contextID = getState() ? getState()->getContextID() : 0;
|
||||
|
||||
// use render to texture stage.
|
||||
// create the render to texture stage.
|
||||
osg::ref_ptr<osgUtil::RenderStage> rtts = dynamic_cast<osgUtil::RenderStage*>(camera.getRenderingCache());
|
||||
osg::ref_ptr<osgUtil::RenderStage> rtts = dynamic_cast<osgUtil::RenderStage*>(camera.getRenderingCache(contextID));
|
||||
if (!rtts)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(camera.getDataChangeMutex());
|
||||
|
||||
rtts = new osgUtil::RenderStage;
|
||||
rtts->setCameraNode(&camera);
|
||||
|
||||
@@ -1126,7 +1129,7 @@ void CullVisitor::apply(osg::CameraNode& camera)
|
||||
rtts->setReadBuffer(previous_stage->getReadBuffer());
|
||||
}
|
||||
|
||||
camera.setRenderingCache(rtts.get());
|
||||
camera.setRenderingCache(contextID, rtts.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -286,6 +286,8 @@ void RenderStage::runCameraSetUp(osg::State& state)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Setting up osg::CameraNode::FRAME_BUFFER_OBJECT"<<std::endl;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_camera->getDataChangeMutex());
|
||||
|
||||
_fbo = new osg::FrameBufferObject;
|
||||
|
||||
setDrawBuffer(GL_NONE);
|
||||
@@ -766,7 +768,7 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
|
||||
|
||||
void RenderStage::drawImplementation(osg::State& state,RenderLeaf*& previous)
|
||||
{
|
||||
|
||||
|
||||
if (!_viewport)
|
||||
{
|
||||
notify(FATAL) << "Error: cannot draw stage due to undefined viewport."<< std::endl;
|
||||
|
||||
@@ -129,18 +129,20 @@ BEGIN_OBJECT_REFLECTOR(osg::CameraNode)
|
||||
I_Method1(void, setGraphicsContext, IN, osg::GraphicsContext *, context);
|
||||
I_Method0(osg::GraphicsContext *, getGraphicsContext);
|
||||
I_Method0(const osg::GraphicsContext *, getGraphicsContext);
|
||||
I_Method1(void, setRenderingCache, IN, osg::Object *, rc);
|
||||
I_Method0(osg::Object *, getRenderingCache);
|
||||
I_Method0(const osg::Object *, getRenderingCache);
|
||||
I_Method2(void, setRenderingCache, IN, unsigned int, contextID, IN, osg::Object *, rc);
|
||||
I_Method1(osg::Object *, getRenderingCache, IN, unsigned int, contextID);
|
||||
I_Method1(const osg::Object *, getRenderingCache, IN, unsigned int, contextID);
|
||||
I_Method1(void, setPostDrawCallback, IN, osg::CameraNode::DrawCallback *, cb);
|
||||
I_Method0(osg::CameraNode::DrawCallback *, getPostDrawCallback);
|
||||
I_Method0(const osg::CameraNode::DrawCallback *, getPostDrawCallback);
|
||||
I_Method0(OpenThreads::Mutex &, getDataChangeMutex);
|
||||
I_Method2(bool, computeLocalToWorldMatrix, IN, osg::Matrix &, matrix, IN, osg::NodeVisitor *, x);
|
||||
I_Method2(bool, computeWorldToLocalMatrix, IN, osg::Matrix &, matrix, IN, osg::NodeVisitor *, x);
|
||||
I_ReadOnlyProperty(osg::CameraNode::BufferAttachmentMap &, BufferAttachmentMap);
|
||||
I_Property(const osg::Vec4 &, ClearColor);
|
||||
I_Property(GLbitfield, ClearMask);
|
||||
I_Property(osg::ColorMask *, ColorMask);
|
||||
I_ReadOnlyProperty(OpenThreads::Mutex &, DataChangeMutex);
|
||||
I_Property(GLenum, DrawBuffer);
|
||||
I_Property(osg::GraphicsContext *, GraphicsContext);
|
||||
I_ReadOnlyProperty(osg::Matrixd, InverseViewMatrix);
|
||||
@@ -150,7 +152,7 @@ BEGIN_OBJECT_REFLECTOR(osg::CameraNode)
|
||||
I_Property(osg::CameraNode::RenderOrder, RenderOrder);
|
||||
I_ReadOnlyProperty(osg::CameraNode::RenderTargetImplementation, RenderTargetFallback);
|
||||
I_Property(osg::CameraNode::RenderTargetImplementation, RenderTargetImplementation);
|
||||
I_Property(osg::Object *, RenderingCache);
|
||||
I_IndexedProperty1(osg::Object *, RenderingCache, unsigned int, contextID);
|
||||
I_Property(osg::CameraNode::TransformOrder, TransformOrder);
|
||||
I_Property(const osg::Matrixd &, ViewMatrix);
|
||||
I_Property(osg::Viewport *, Viewport);
|
||||
|
||||
Reference in New Issue
Block a user