From Art Trevs, moved multile render targets support from RenderStage into FrameBufferObject.

From Robert Osfield, refactored the FrameBufferObejcts::_drawBuffers set up so that its done
within the setAttachment  method to avoid potential threading/execution order issues.
This commit is contained in:
Robert Osfield
2008-04-15 19:36:40 +00:00
parent e1c6a6ea43
commit 9724303f38
5 changed files with 73 additions and 38 deletions

View File

@@ -296,18 +296,24 @@ namespace osg
{
public:
typedef std::map<GLenum, FrameBufferAttachment> AttachmentMap;
typedef std::vector<GLenum> MultipleRenderingTargets;
FrameBufferObject();
FrameBufferObject(const FrameBufferObject& copy, const CopyOp& copyop = CopyOp::SHALLOW_COPY);
META_StateAttribute(osg, FrameBufferObject, (StateAttribute::Type)0x101010/*FrameBufferObject*/);
inline const AttachmentMap &getAttachmentMap() const;
inline const AttachmentMap& getAttachmentMap() const;
inline bool hasAttachment(GLenum attachment_point) const;
void setAttachment(GLenum attachment_point, const FrameBufferAttachment &attachment);
inline const FrameBufferAttachment& getAttachment(GLenum attachment_point) const;
inline void setAttachment(GLenum attachment_point, const FrameBufferAttachment &attachment);
inline bool hasMultipleRenderingTargets() const { return !_drawBuffers.empty(); }
inline const MultipleRenderingTargets& getMultipleRenderingTargets() const { return _drawBuffers; }
int compare(const StateAttribute &sa) const;
void apply(State &state) const;
/** Mark internal FBO for deletion.
@@ -330,10 +336,15 @@ namespace osg
inline void dirtyAll();
private:
AttachmentMap _attachments;
mutable buffered_value<int> _dirtyAttachmentList;
mutable buffered_value<int> _unsupported;
mutable buffered_value<GLuint> _fboID;
AttachmentMap _attachments;
// Buffers passed to glDrawBuffers when using multiple render targets.
MultipleRenderingTargets _drawBuffers;
mutable buffered_value<int> _dirtyAttachmentList;
mutable buffered_value<int> _unsupported;
mutable buffered_value<GLuint> _fboID;
};
// INLINE METHODS
@@ -353,12 +364,6 @@ namespace osg
return _attachments.find(attachment_point)->second;
}
inline void FrameBufferObject::setAttachment(GLenum attachment_point, const FrameBufferAttachment &attachment)
{
_attachments[attachment_point] = attachment;
dirtyAll();
}
inline void FrameBufferObject::dirtyAll()
{
_dirtyAttachmentList.setAllElementsTo(1);

View File

@@ -226,8 +226,6 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
GLenum _drawBuffer;
GLenum _readBuffer;
// Buffers passed to glDrawBuffers when using multiple render targets.
std::vector<GLenum> _drawBuffers;
GLbitfield _clearMask;
osg::ref_ptr<osg::ColorMask> _colorMask;
osg::Vec4 _clearColor;

View File

@@ -556,7 +556,8 @@ FrameBufferObject::FrameBufferObject()
FrameBufferObject::FrameBufferObject(const FrameBufferObject &copy, const CopyOp &copyop)
: StateAttribute(copy, copyop),
_attachments(copy._attachments)
_attachments(copy._attachments),
_drawBuffers(copy._drawBuffers)
{
}
@@ -568,6 +569,26 @@ FrameBufferObject::~FrameBufferObject()
}
}
void FrameBufferObject::setAttachment(GLenum attachment_point, const FrameBufferAttachment &attachment)
{
_attachments[attachment_point] = attachment;
_drawBuffers.clear();
// create textures and mipmaps before we bind the frame buffer object
for (AttachmentMap::const_iterator i=_attachments.begin(); i!=_attachments.end(); ++i)
{
const FrameBufferAttachment &fa = i->second;
// setup draw buffers based on the attachment definition
if (i->first >= GL_COLOR_ATTACHMENT0_EXT && i->first <= GL_COLOR_ATTACHMENT15_EXT)
_drawBuffers.push_back(i->first);
}
dirtyAll();
}
void FrameBufferObject::apply(State &state) const
{
unsigned int contextID = state.getContextID();
@@ -615,7 +636,6 @@ void FrameBufferObject::apply(State &state) const
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)
{
@@ -628,6 +648,16 @@ void FrameBufferObject::apply(State &state) const
ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
// enable drawing buffers to render the result to fbo
if (_drawBuffers.size() > 0)
{
GL2Extensions *gl2e = GL2Extensions::Get(state.getContextID(), true );
if (gl2e)
{
gl2e->glDrawBuffers(_drawBuffers.size(), &(_drawBuffers[0]));
}
}
if (dirtyAttachmentList)
{
for (AttachmentMap::const_iterator i=_attachments.begin(); i!=_attachments.end(); ++i)

View File

@@ -92,7 +92,6 @@ RenderStage::RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop):
_viewport(rhs._viewport),
_drawBuffer(rhs._drawBuffer),
_readBuffer(rhs._readBuffer),
_drawBuffers(rhs._drawBuffers),
_clearMask(rhs._clearMask),
_colorMask(rhs._colorMask),
_clearColor(rhs._clearColor),
@@ -332,7 +331,6 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
bool colorAttached = false;
bool depthAttached = false;
bool stencilAttached = false;
_drawBuffers.clear(); // MRT buffers
for(osg::Camera::BufferAttachmentMap::iterator itr = bufferAttachments.begin();
itr != bufferAttachments.end();
@@ -366,9 +364,6 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
{
fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT+(buffer-osg::Camera::COLOR_BUFFER0), osg::FrameBufferAttachment(attachment));
colorAttached = true;
// append to MRT buffer list
_drawBuffers.push_back(GL_COLOR_ATTACHMENT0_EXT+(buffer-osg::Camera::COLOR_BUFFER0));
break;
}
}
@@ -395,7 +390,6 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
fbo_supported = false;
fbo_ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
fbo = 0;
_drawBuffers.clear();
// clean up.
double availableTime = 100.0f;
@@ -707,7 +701,10 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b
{
osg::State& state = *renderInfo.getState();
bool using_multiple_render_targets = !(_drawBuffers.empty());
osg::FBOExtensions* fbo_ext = _fbo.valid() ? osg::FBOExtensions::instance(state.getContextID(),true) : 0;
bool fbo_supported = fbo_ext && fbo_ext->isSupported();
bool using_multiple_render_targets = fbo_supported && _fbo->hasMultipleRenderingTargets();
if (!using_multiple_render_targets)
{
@@ -722,21 +719,9 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b
}
}
osg::FBOExtensions* fbo_ext = _fbo.valid() ? osg::FBOExtensions::instance(state.getContextID(),true) : 0;
bool fbo_supported = fbo_ext && fbo_ext->isSupported();
if (fbo_supported)
{
_fbo->apply(state);
if (using_multiple_render_targets)
{
GL2Extensions *gl2e = GL2Extensions::Get(state.getContextID(), true );
if (gl2e)
{
gl2e->glDrawBuffers(_drawBuffers.size(), &(_drawBuffers[0]));
}
}
}
// do the drawing itself.
@@ -774,7 +759,7 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b
int attachment=itr->first;
if (attachment==osg::Camera::DEPTH_BUFFER || attachment==osg::Camera::STENCIL_BUFFER) {
// assume first buffer rendered to is the one we want
glReadBuffer(_drawBuffers[0]);
glReadBuffer(_fbo->getMultipleRenderingTargets()[0]);
} else {
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + (attachment - osg::Camera::COLOR_BUFFER0));
}

View File

@@ -159,6 +159,8 @@ END_REFLECTOR
TYPE_NAME_ALIAS(std::map< GLenum COMMA osg::FrameBufferAttachment >, osg::FrameBufferObject::AttachmentMap)
TYPE_NAME_ALIAS(std::vector< GLenum >, osg::FrameBufferObject::MultipleRenderingTargets)
BEGIN_OBJECT_REFLECTOR(osg::FrameBufferObject)
I_DeclaringFile("osg/FrameBufferObject");
I_BaseType(osg::StateAttribute);
@@ -209,14 +211,24 @@ BEGIN_OBJECT_REFLECTOR(osg::FrameBufferObject)
__bool__hasAttachment__GLenum,
"",
"");
I_Method2(void, setAttachment, IN, GLenum, attachment_point, IN, const osg::FrameBufferAttachment &, attachment,
Properties::NON_VIRTUAL,
__void__setAttachment__GLenum__C5_FrameBufferAttachment_R1,
"",
"");
I_Method1(const osg::FrameBufferAttachment &, getAttachment, IN, GLenum, attachment_point,
Properties::NON_VIRTUAL,
__C5_FrameBufferAttachment_R1__getAttachment__GLenum,
"",
"");
I_Method2(void, setAttachment, IN, GLenum, attachment_point, IN, const osg::FrameBufferAttachment &, attachment,
I_Method0(bool, hasMultipleRenderingTargets,
Properties::NON_VIRTUAL,
__void__setAttachment__GLenum__C5_FrameBufferAttachment_R1,
__bool__hasMultipleRenderingTargets,
"",
"");
I_Method0(const osg::FrameBufferObject::MultipleRenderingTargets &, getMultipleRenderingTargets,
Properties::NON_VIRTUAL,
__C5_MultipleRenderingTargets_R1__getMultipleRenderingTargets,
"",
"");
I_Method1(int, compare, IN, const osg::StateAttribute &, sa,
@@ -254,6 +266,9 @@ BEGIN_OBJECT_REFLECTOR(osg::FrameBufferObject)
I_SimpleProperty(const osg::FrameBufferObject::AttachmentMap &, AttachmentMap,
__C5_AttachmentMap_R1__getAttachmentMap,
0);
I_SimpleProperty(const osg::FrameBufferObject::MultipleRenderingTargets &, MultipleRenderingTargets,
__C5_MultipleRenderingTargets_R1__getMultipleRenderingTargets,
0);
I_SimpleProperty(osg::StateAttribute::Type, Type,
__Type__getType,
0);
@@ -374,3 +389,5 @@ END_REFLECTOR
STD_MAP_REFLECTOR(std::map< GLenum COMMA osg::FrameBufferAttachment >)
STD_VECTOR_REFLECTOR(std::vector< GLenum >)