From Wojciech Lewandowski, support for FBO's without colour or depth attachments.

Note from Robert Osfield, I've temporarily re-enabled the old focing of of color and depth attachment to avoid regressions on some OpenGL driver.  We'll revist this once
we have a mechanism for controlling this override at runtime.

#define FORCE_COLOR_ATTACHMENT  1
#define FORCE_DEPTH_ATTACHMENT  1
This commit is contained in:
Robert Osfield
2009-08-21 09:34:48 +00:00
parent 65352c8533
commit 3f65f4f80b
7 changed files with 140 additions and 91 deletions

View File

@@ -294,14 +294,14 @@ class OSG_EXPORT Camera : public Transform, public CullSettings
/** Set the draw buffer used at the start of each frame draw.
* Note, a buffer value of GL_NONE is used to sepecify that the rendering back-end should choose the most appropriate buffer.*/
void setDrawBuffer(GLenum buffer) { _drawBuffer = buffer; }
void setDrawBuffer(GLenum buffer) { _drawBuffer = buffer; applyMaskAction( DRAW_BUFFER ); }
/** Get the draw buffer used at the start of each frame draw. */
GLenum getDrawBuffer() const { return _drawBuffer; }
/** Set the read buffer for any required copy operations to use.
* Note, a buffer value of GL_NONE is used to sepecify that the rendering back-end should choose the most appropriate buffer.*/
void setReadBuffer(GLenum buffer) { _readBuffer = buffer; }
void setReadBuffer(GLenum buffer) { _readBuffer = buffer; applyMaskAction( READ_BUFFER ); }
/** Get the read buffer for any required copy operations to use. */
GLenum getReadBuffer() const { return _readBuffer; }

View File

@@ -58,25 +58,27 @@ class OSG_EXPORT CullSettings
enum VariablesMask
{
COMPUTE_NEAR_FAR_MODE = 0x0001,
CULLING_MODE = 0x0002,
LOD_SCALE = 0x0004,
SMALL_FEATURE_CULLING_PIXEL_SIZE = 0x0008,
CLAMP_PROJECTION_MATRIX_CALLBACK = 0x0010,
NEAR_FAR_RATIO = 0x0020,
IMPOSTOR_ACTIVE = 0x0040,
DEPTH_SORT_IMPOSTOR_SPRITES = 0x0080,
IMPOSTOR_PIXEL_ERROR_THRESHOLD = 0x0100,
NUM_FRAMES_TO_KEEP_IMPOSTORS_SPRITES = 0x0200,
CULL_MASK = 0x0400,
CULL_MASK_LEFT = 0x0800,
CULL_MASK_RIGHT = 0x1000,
CLEAR_COLOR = 0x2000,
LIGHTING_MODE = 0x4000,
LIGHT = 0x8000,
NO_VARIABLES = 0x0000,
ALL_VARIABLES = 0xFFFF
COMPUTE_NEAR_FAR_MODE = 0x00000001,
CULLING_MODE = 0x00000002,
LOD_SCALE = 0x00000004,
SMALL_FEATURE_CULLING_PIXEL_SIZE = 0x00000008,
CLAMP_PROJECTION_MATRIX_CALLBACK = 0x00000010,
NEAR_FAR_RATIO = 0x00000020,
IMPOSTOR_ACTIVE = 0x00000040,
DEPTH_SORT_IMPOSTOR_SPRITES = 0x00000080,
IMPOSTOR_PIXEL_ERROR_THRESHOLD = 0x00000100,
NUM_FRAMES_TO_KEEP_IMPOSTORS_SPRITES = 0x00000200,
CULL_MASK = 0x00000400,
CULL_MASK_LEFT = 0x00000800,
CULL_MASK_RIGHT = 0x00001000,
CLEAR_COLOR = 0x00002000,
LIGHTING_MODE = 0x00004000,
LIGHT = 0x00008000,
DRAW_BUFFER = 0x00010000,
READ_BUFFER = 0x00020000,
NO_VARIABLES = 0x00000000,
ALL_VARIABLES = 0xFFFFFFFF
};
/** Set the inheritance mask used in inheritCullSettings to control which variables get overwritten by the passed in CullSettings object.*/

View File

@@ -53,17 +53,31 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
/** Set the draw buffer used at the start of each frame draw. */
void setDrawBuffer(GLenum buffer) { _drawBuffer = buffer; }
void setDrawBuffer(GLenum buffer, bool applyMask = true ) { _drawBuffer = buffer; setDrawBufferApplyMask( applyMask ); }
/** Get the draw buffer used at the start of each frame draw. */
GLenum getDrawBuffer() const { return _drawBuffer; }
/** Get the apply mask defining whether glDrawBuffer is called at each frame draw. */
bool getDrawBufferApplyMask() const { return _drawBufferApplyMask; }
/** Set the apply mask defining whether glDrawBuffer is called at each frame draw. */
void setDrawBufferApplyMask( bool applyMask ) { _drawBufferApplyMask = applyMask; }
/** Set the read buffer for any required copy operations to use. */
void setReadBuffer(GLenum buffer) { _readBuffer = buffer; }
void setReadBuffer(GLenum buffer, bool applyMask = true) { _readBuffer = buffer; setReadBufferApplyMask( applyMask ); }
/** Get the read buffer for any required copy operations to use. */
GLenum getReadBuffer() const { return _readBuffer; }
/** Get the apply mask defining whether glReadBuffer is called at each frame draw. */
bool getReadBufferApplyMask() const { return _readBufferApplyMask; }
/** Set the apply mask defining whether glReadBuffer is called at each frame draw. */
void setReadBufferApplyMask( bool applyMask ) { _readBufferApplyMask = applyMask; }
/** Set the viewport.*/
void setViewport(osg::Viewport* viewport) { _viewport = viewport; }
@@ -251,7 +265,9 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
osg::ref_ptr<osg::Viewport> _viewport;
GLenum _drawBuffer;
bool _drawBufferApplyMask;
GLenum _readBuffer;
bool _readBufferApplyMask;
GLbitfield _clearMask;
osg::ref_ptr<osg::ColorMask> _colorMask;
osg::Vec4 _clearColor;

View File

@@ -386,11 +386,18 @@ void Camera::inheritCullSettings(const CullSettings& settings, unsigned int inhe
{
CullSettings::inheritCullSettings(settings, inheritanceMask);
if (inheritanceMask & CLEAR_COLOR)
const Camera* camera = dynamic_cast<const Camera*>(&settings);
if (camera)
{
//osg::notify(osg::NOTICE)<<"Inheriting slave Camera"<<std::endl;
const Camera* camera = dynamic_cast<const Camera*>(&settings);
_clearColor = camera->_clearColor;
if (inheritanceMask & CLEAR_COLOR)
_clearColor = camera->_clearColor;
if (inheritanceMask & DRAW_BUFFER)
_drawBuffer = camera->_drawBuffer;
if (inheritanceMask & READ_BUFFER)
_drawBuffer = camera->_readBuffer;
}
}

View File

@@ -1262,26 +1262,25 @@ void CullVisitor::apply(osg::Camera& camera)
rtts->setCamera(&camera);
if (camera.getDrawBuffer() != GL_NONE)
if ( camera.getInheritanceMask() & DRAW_BUFFER )
{
// inherit draw buffer from above.
rtts->setDrawBuffer(previous_stage->getDrawBuffer(),previous_stage->getDrawBufferApplyMask());
}
else
{
rtts->setDrawBuffer(camera.getDrawBuffer());
}
else
if ( camera.getInheritanceMask() & READ_BUFFER )
{
// inherit draw buffer from above.
rtts->setDrawBuffer(previous_stage->getDrawBuffer());
// inherit read buffer from above.
rtts->setReadBuffer(previous_stage->getReadBuffer(), previous_stage->getReadBufferApplyMask());
}
if (camera.getReadBuffer() != GL_NONE)
else
{
rtts->setReadBuffer(camera.getReadBuffer());
}
else
{
// inherit read buffer from above.
rtts->setReadBuffer(previous_stage->getReadBuffer());
}
}
else
{
@@ -1305,6 +1304,7 @@ void CullVisitor::apply(osg::Camera& camera)
{
rtts->setClearColor(camera.getClearColor());
}
// set the color mask.
osg::ColorMask* colorMask = camera.getColorMask()!=0 ? camera.getColorMask() : previous_stage->getColorMask();

View File

@@ -25,6 +25,8 @@
#include <osgUtil/RenderStage>
#define FORCE_COLOR_ATTACHMENT 1
#define FORCE_DEPTH_ATTACHMENT 1
using namespace osg;
using namespace osgUtil;
@@ -42,7 +44,10 @@ RenderStage::RenderStage():
_stageDrawnThisFrame = false;
_drawBuffer = GL_NONE;
_drawBufferApplyMask = false;
_readBuffer = GL_NONE;
_readBufferApplyMask = false;
_clearMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
_clearColor.set(0.0f,0.0f,0.0f,0.0f);
_clearAccum.set(0.0f,0.0f,0.0f,0.0f);
@@ -69,7 +74,10 @@ RenderStage::RenderStage(SortMode mode):
_stageDrawnThisFrame = false;
_drawBuffer = GL_NONE;
_drawBufferApplyMask = false;
_readBuffer = GL_NONE;
_readBufferApplyMask = false;
_clearMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
_clearColor.set(0.0f,0.0f,0.0f,0.0f);
_clearAccum.set(0.0f,0.0f,0.0f,0.0f);
@@ -93,7 +101,9 @@ RenderStage::RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop):
_postRenderList(rhs._postRenderList),
_viewport(rhs._viewport),
_drawBuffer(rhs._drawBuffer),
_drawBufferApplyMask(rhs._drawBufferApplyMask),
_readBuffer(rhs._readBuffer),
_readBufferApplyMask(rhs._readBufferApplyMask),
_clearMask(rhs._clearMask),
_colorMask(rhs._colorMask),
_clearColor(rhs._clearColor),
@@ -226,6 +236,7 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
osg::Camera::BufferAttachmentMap& bufferAttachments = _camera->getBufferAttachmentMap();
// compute the required dimensions
int width = static_cast<int>(_viewport->x() + _viewport->width());
int height = static_cast<int>(_viewport->y() + _viewport->height());
@@ -419,6 +430,7 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
}
#if FORCE_DEPTH_ATTACHMENT
if (!depthAttached)
{
fbo->setAttachment(osg::Camera::DEPTH_BUFFER, osg::FrameBufferAttachment(new osg::RenderBuffer(width, height, GL_DEPTH_COMPONENT24)));
@@ -428,10 +440,13 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
osg::FrameBufferAttachment(new osg::RenderBuffer(width,
height, GL_DEPTH_COMPONENT24, samples, colorSamples)));
}
depthAttached = true;
}
#endif
#if FORCE_COLOR_ATTACHMENT
if (!colorAttached)
{
{
fbo->setAttachment(osg::Camera::COLOR_BUFFER, osg::FrameBufferAttachment(new osg::RenderBuffer(width, height, GL_RGB)));
if (fbo_multisample.valid())
{
@@ -439,12 +454,26 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
osg::FrameBufferAttachment(new osg::RenderBuffer(width,
height, GL_RGB, samples, colorSamples)));
}
colorAttached = true;
}
#endif
fbo->apply(state);
// If no color attachment make sure to set glDrawBuffer/glReadBuffer to none
// otherwise glCheckFramebufferStatusEXT will fail
// It has to be done after call to glBindFramebuffer (fbo->apply)
// and before call to glCheckFramebufferStatus
if ( !colorAttached )
{
setDrawBuffer( GL_NONE, true );
glDrawBuffer( GL_NONE );
setReadBuffer( GL_NONE, true );
glReadBuffer( GL_NONE );
}
GLenum status = fbo_ext->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
{
osg::notify(osg::NOTICE)<<"RenderStage::runCameraSetUp(), FBO setup failed, FBO status= 0x"<<std::hex<<status<<std::dec<<std::endl;
@@ -463,8 +492,8 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
}
else
{
setDrawBuffer(GL_NONE);
setReadBuffer(GL_NONE);
setDrawBuffer(GL_NONE, false );
setReadBuffer(GL_NONE, false );
_fbo = fbo;
@@ -730,7 +759,7 @@ void RenderStage::copyTexture(osg::RenderInfo& renderInfo)
{
osg::State& state = *renderInfo.getState();
if (_readBuffer != GL_NONE)
if ( _readBufferApplyMask )
{
glReadBuffer(_readBuffer);
}
@@ -831,15 +860,11 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b
if (!using_multiple_render_targets)
{
if (_drawBuffer != GL_NONE)
{
if( getDrawBufferApplyMask() )
glDrawBuffer(_drawBuffer);
}
if (_readBuffer != GL_NONE)
{
if( getReadBufferApplyMask() )
glReadBuffer(_readBuffer);
}
}
if (fbo_supported)

View File

@@ -138,8 +138,7 @@ SceneView::SceneView(DisplaySettings* ds)
_initCalled = false;
setDrawBufferValue(GL_BACK);
_camera->setDrawBuffer(GL_BACK);
_requiresFlush = true;
@@ -1082,13 +1081,13 @@ void SceneView::draw()
break;
case(osg::DisplaySettings::ANAGLYPHIC):
{
if( getDrawBufferValue() != GL_NONE)
if( 0 == ( _camera->getInheritanceMask() & DRAW_BUFFER ) )
{
_renderStageLeft->setDrawBuffer(getDrawBufferValue());
_renderStageLeft->setReadBuffer(getDrawBufferValue());
_renderStageLeft->setDrawBuffer(_camera->getDrawBuffer());
_renderStageLeft->setReadBuffer(_camera->getDrawBuffer());
_renderStageRight->setDrawBuffer(getDrawBufferValue());
_renderStageRight->setReadBuffer(getDrawBufferValue());
_renderStageRight->setDrawBuffer(_camera->getDrawBuffer());
_renderStageRight->setReadBuffer(_camera->getDrawBuffer());
}
_localStateSet->setAttribute(getViewport());
@@ -1142,13 +1141,13 @@ void SceneView::draw()
break;
case(osg::DisplaySettings::HORIZONTAL_SPLIT):
{
if( getDrawBufferValue() != GL_NONE)
if( 0 == ( _camera->getInheritanceMask() & DRAW_BUFFER) )
{
_renderStageLeft->setDrawBuffer(getDrawBufferValue());
_renderStageLeft->setReadBuffer(getDrawBufferValue());
_renderStageLeft->setDrawBuffer(_camera->getDrawBuffer());
_renderStageLeft->setReadBuffer(_camera->getDrawBuffer());
_renderStageRight->setDrawBuffer(getDrawBufferValue());
_renderStageRight->setReadBuffer(getDrawBufferValue());
_renderStageRight->setDrawBuffer(_camera->getDrawBuffer());
_renderStageRight->setReadBuffer(_camera->getDrawBuffer());
}
// ensure that all color planes are active.
@@ -1191,13 +1190,13 @@ void SceneView::draw()
break;
case(osg::DisplaySettings::VERTICAL_SPLIT):
{
if( getDrawBufferValue() != GL_NONE)
if( 0 == ( _camera->getInheritanceMask() & DRAW_BUFFER) )
{
_renderStageLeft->setDrawBuffer(getDrawBufferValue());
_renderStageLeft->setReadBuffer(getDrawBufferValue());
_renderStageLeft->setDrawBuffer(_camera->getDrawBuffer());
_renderStageLeft->setReadBuffer(_camera->getDrawBuffer());
_renderStageRight->setDrawBuffer(getDrawBufferValue());
_renderStageRight->setReadBuffer(getDrawBufferValue());
_renderStageRight->setDrawBuffer(_camera->getDrawBuffer());
_renderStageRight->setReadBuffer(_camera->getDrawBuffer());
}
// ensure that all color planes are active.
@@ -1241,10 +1240,10 @@ void SceneView::draw()
case(osg::DisplaySettings::RIGHT_EYE):
case(osg::DisplaySettings::LEFT_EYE):
{
if( getDrawBufferValue() != GL_NONE)
if( 0 == ( _camera->getInheritanceMask() & DRAW_BUFFER) )
{
_renderStage->setDrawBuffer(getDrawBufferValue());
_renderStage->setReadBuffer(getDrawBufferValue());
_renderStage->setDrawBuffer(_camera->getDrawBuffer());
_renderStage->setReadBuffer(_camera->getDrawBuffer());
}
// ensure that all color planes are active.
@@ -1268,12 +1267,12 @@ void SceneView::draw()
break;
case(osg::DisplaySettings::VERTICAL_INTERLACE):
{
if( getDrawBufferValue() != GL_NONE)
if( 0 == ( _camera->getInheritanceMask() & DRAW_BUFFER) )
{
_renderStageLeft->setDrawBuffer(getDrawBufferValue());
_renderStageLeft->setReadBuffer(getDrawBufferValue());
_renderStageRight->setDrawBuffer(getDrawBufferValue());
_renderStageRight->setReadBuffer(getDrawBufferValue());
_renderStageLeft->setDrawBuffer(_camera->getDrawBuffer());
_renderStageLeft->setReadBuffer(_camera->getDrawBuffer());
_renderStageRight->setDrawBuffer(_camera->getDrawBuffer());
_renderStageRight->setReadBuffer(_camera->getDrawBuffer());
}
_localStateSet->setAttribute(getViewport());
@@ -1345,13 +1344,13 @@ void SceneView::draw()
break;
case(osg::DisplaySettings::HORIZONTAL_INTERLACE):
{
if( getDrawBufferValue() != GL_NONE)
{
_renderStageLeft->setDrawBuffer(getDrawBufferValue());
_renderStageLeft->setReadBuffer(getDrawBufferValue());
_renderStageRight->setDrawBuffer(getDrawBufferValue());
_renderStageRight->setReadBuffer(getDrawBufferValue());
}
if( 0 == ( _camera->getInheritanceMask() & DRAW_BUFFER) )
{
_renderStageLeft->setDrawBuffer(_camera->getDrawBuffer());
_renderStageLeft->setReadBuffer(_camera->getDrawBuffer());
_renderStageRight->setDrawBuffer(_camera->getDrawBuffer());
_renderStageRight->setReadBuffer(_camera->getDrawBuffer());
}
_localStateSet->setAttribute(getViewport());
// ensure that all color planes are active.
@@ -1422,13 +1421,13 @@ void SceneView::draw()
break;
case(osg::DisplaySettings::CHECKERBOARD):
{
if( getDrawBufferValue() != GL_NONE)
{
_renderStageLeft->setDrawBuffer(getDrawBufferValue());
_renderStageLeft->setReadBuffer(getDrawBufferValue());
_renderStageRight->setDrawBuffer(getDrawBufferValue());
_renderStageRight->setReadBuffer(getDrawBufferValue());
}
if( 0 == ( _camera->getInheritanceMask() & DRAW_BUFFER) )
{
_renderStageLeft->setDrawBuffer(_camera->getDrawBuffer());
_renderStageLeft->setReadBuffer(_camera->getDrawBuffer());
_renderStageRight->setDrawBuffer(_camera->getDrawBuffer());
_renderStageRight->setReadBuffer(_camera->getDrawBuffer());
}
_localStateSet->setAttribute(getViewport());
// ensure that all color planes are active.
@@ -1508,13 +1507,13 @@ void SceneView::draw()
{
// Need to restore draw buffer when toggling Stereo off.
if( _camera->getDrawBuffer() != GL_NONE)
if( 0 == ( _camera->getInheritanceMask() & DRAW_BUFFER ) )
{
_renderStage->setDrawBuffer(_camera->getDrawBuffer());
_renderStage->setReadBuffer(_camera->getDrawBuffer());
}
if( _camera->getReadBuffer() != GL_NONE)
if( 0 == ( _camera->getInheritanceMask() & READ_BUFFER ) )
{
_renderStage->setReadBuffer(_camera->getReadBuffer());
}