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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -556,7 +556,8 @@ FrameBufferObject::FrameBufferObject()
|
||||
|
||||
FrameBufferObject::FrameBufferObject(const FrameBufferObject ©, const CopyOp ©op)
|
||||
: 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)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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 >)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user