Added multi-buffering of the CameraNode::_renderingCache to help cope with multiple graphis context usages.

This commit is contained in:
Robert Osfield
2005-11-23 13:44:27 +00:00
parent b4fb878e1e
commit 74830f9ce1
5 changed files with 34 additions and 25 deletions

View File

@@ -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;
};
}

View File

@@ -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

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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);