diff --git a/VisualStudio/osgUtil/osgUtil.dsp b/VisualStudio/osgUtil/osgUtil.dsp index 0846054fa..7f6df2aa7 100755 --- a/VisualStudio/osgUtil/osgUtil.dsp +++ b/VisualStudio/osgUtil/osgUtil.dsp @@ -151,10 +151,6 @@ SOURCE=..\..\src\osgUtil\RenderStageLighting.cpp # End Source File # Begin Source File -SOURCE=..\..\src\osgUtil\RenderToTextureStage.cpp -# End Source File -# Begin Source File - SOURCE=..\..\src\osgUtil\SceneView.cpp # End Source File # Begin Source File @@ -267,10 +263,6 @@ SOURCE=..\..\include\osgUtil\RenderStageLighting # End Source File # Begin Source File -SOURCE=..\..\include\osgUtil\RenderToTextureStage -# End Source File -# Begin Source File - SOURCE=..\..\Include\osgUtil\SceneView # End Source File # Begin Source File diff --git a/include/osg/CameraNode b/include/osg/CameraNode index 7064e8438..54ca14d18 100644 --- a/include/osg/CameraNode +++ b/include/osg/CameraNode @@ -66,6 +66,8 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings ColorMask* getColorMask() { return _colorMask.get(); } + + /** Set the viewport of the camera to use specified osg::Viewport. */ void setViewport(osg::Viewport* viewport); @@ -192,28 +194,35 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings RenderTargetImplementation getRenderTargetImplmentation() const { return _renderTargetImplementation; } - /** Set the draw buffer for a given fragment output position to specified draw buffer. */ - void setDrawBuffer(unsigned int pos, GLenum buffer) { _drawBufferList[pos] = buffer; } + /** 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; } - /** Get the draw buffer for a given fragment output position. */ - GLenum getDrawBuffer(unsigned int pos) const { return _drawBufferList[pos]; } - - typedef std::vector DrawBufferList; + /** Get the draw buffer used at the start of each frame draw. */ + GLenum getDrawBuffer() const { return _drawBuffer; } - /** Get the list which draw buffer are active. */ - DrawBufferList& getDrawBufferList() { return _drawBufferList; } - - /** Get the const list which draw buffer are active. */ - const DrawBufferList& getDrawBufferList() const { return _drawBufferList; } - - - /** Set the read buffer for any required copy operations to use. */ + /** 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; } /** Get the read buffer for any required copy operations to use. */ GLenum getReadBuffer() const { return _readBuffer; } + /** Set the render buffer for a given fragment output position to specified draw buffer. */ + void setRenderBuffer(unsigned int pos, GLenum buffer) { _renderBufferList[pos] = buffer; } + + /** Get the draw buffer for a given fragment output position. */ + GLenum getRenderBuffer(unsigned int pos) const { return _renderBufferList[pos]; } + + typedef std::vector RenderBufferList; + + /** Get the list which draw buffer are active. */ + RenderBufferList& getRenderBufferList() { return _renderBufferList; } + + /** Get the const list which draw buffer are active. */ + const RenderBufferList& getRenderBufferList() const { return _renderBufferList; } + enum BufferComponent { DEPTH_BUFFER, @@ -318,7 +327,7 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings Vec4 _clearColor; GLbitfield _clearMask; - ref_ptr _colorMask; + ref_ptr _colorMask; ref_ptr _viewport; TransformOrder _transformOrder; @@ -327,8 +336,9 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings RenderOrder _renderOrder; - DrawBufferList _drawBufferList; + GLenum _drawBuffer; GLenum _readBuffer; + RenderBufferList _renderBufferList; RenderTargetImplementation _renderTargetImplementation; BufferAttachmentMap _bufferAttachmentMap; diff --git a/include/osgUtil/RenderStage b/include/osgUtil/RenderStage index f67912d9b..10ffd83be 100644 --- a/include/osgUtil/RenderStage +++ b/include/osgUtil/RenderStage @@ -16,6 +16,9 @@ #include #include +#include +#include +#include #include #include @@ -49,6 +52,19 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin virtual void reset(); + /** Set the draw buffer used at the start of each frame draw. */ + void setDrawBuffer(GLenum buffer) { _drawBuffer = 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. */ + void setReadBuffer(GLenum buffer) { _readBuffer = buffer; } + + /** Get the read buffer for any required copy operations to use. */ + GLenum getReadBuffer() const { return _readBuffer; } + + /** Set the viewport.*/ void setViewport(osg::Viewport* viewport) { _viewport = viewport; } @@ -58,8 +74,6 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin /** Get the viewport. */ osg::Viewport* getViewport() { return _viewport.get(); } - - /** Set the clear mask used in glClear(..). * Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */ void setClearMask(GLbitfield mask) { _clearMask = mask; } @@ -105,6 +119,34 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin /** Get the clear color.*/ int getClearStencil() const { return _clearStencil; } + + void setCameraNode(const osg::CameraNode* camera) { _camera = camera; } + const osg::CameraNode* getCameraNode() const { return _camera; } + + void setTexture(osg::Texture* texture, unsigned int level = 0, unsigned int face=0) { _texture = texture; _level = level; _face = face; } + osg::Texture* getTexture() { return _texture.get(); } + + void setImage(osg::Image* image) { _image = image; } + osg::Image* getImage() { return _image.get(); } + + void setImageReadPixelFormat(GLenum format) { _imageReadPixelFormat = format; } + GLenum getImageReadPixelFormat() const { return _imageReadPixelFormat; } + + void setImageReadPixelDataType(GLenum type) { _imageReadPixelDataType = type; } + GLenum getImageReadPixelDataType() const { return _imageReadPixelDataType; } + + + void setFrameBufferObject(osg::FrameBufferObject* fbo) { _fbo = fbo; } + osg::FrameBufferObject* getFrameBufferObject() { return _fbo.get(); } + const osg::FrameBufferObject* getFrameBufferObject() const { return _fbo.get(); } + + void setGraphicsContext(osg::GraphicsContext* context) { _graphicsContext = context; } + osg::GraphicsContext* getGraphicsContext() { return _graphicsContext.get(); } + const osg::GraphicsContext* getGraphicsContext() const { return _graphicsContext.get(); } + + + + void setInheritedRenderStageLightingMatrix(const osg::Matrix& matrix) { _inheritedRenderStageLightingMatrix = matrix; } const osg::Matrix& getInheritedRenderStageLightingMatrix() const { return _inheritedRenderStageLightingMatrix; } @@ -158,6 +200,8 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin // viewport x,y,width,height. osg::ref_ptr _viewport; + GLenum _drawBuffer; + GLenum _readBuffer; GLbitfield _clearMask; osg::ref_ptr _colorMask; osg::Vec4 _clearColor; @@ -165,6 +209,19 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin double _clearDepth; int _clearStencil; + const osg::CameraNode* _camera; + + osg::ref_ptr _texture; + unsigned int _level; + unsigned int _face; + + osg::ref_ptr _image; + GLenum _imageReadPixelFormat; + GLenum _imageReadPixelDataType; + + osg::ref_ptr _fbo; + osg::ref_ptr _graphicsContext; + mutable osg::Matrix _inheritedRenderStageLightingMatrix; mutable osg::ref_ptr _inheritedRenderStageLighting; mutable osg::ref_ptr _renderStageLighting; diff --git a/include/osgUtil/RenderToTextureStage b/include/osgUtil/RenderToTextureStage deleted file mode 100644 index 08e03feb9..000000000 --- a/include/osgUtil/RenderToTextureStage +++ /dev/null @@ -1,96 +0,0 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield - * - * This library is open source and may be redistributed and/or modified under - * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or - * (at your option) any later version. The full license is in LICENSE file - * included with this distribution, and on the openscenegraph.org website. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * OpenSceneGraph Public License for more details. -*/ - -#ifndef OSGUTIL_RENDERTOTEXTURESTAGE -#define OSGUTIL_RENDERTOTEXTURESTAGE 1 - -#include -#include -#include - -#include - -namespace osgUtil { - -/** - * RenderStage which copies the final image to an attached texture or image. - * Generally used as a pre-rendering stage. - */ -class OSGUTIL_EXPORT RenderToTextureStage : public RenderStage -{ - public: - - - RenderToTextureStage(); - - - virtual osg::Object* cloneType() const { return new RenderToTextureStage(); } - virtual osg::Object* clone(const osg::CopyOp&) const { return new RenderToTextureStage(); } // note only implements a clone of type. - virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=0L; } - virtual const char* libraryName() const { return "osgUtil"; } - virtual const char* className() const { return "RenderToTextureStage"; } - - virtual void reset(); - - void setCameraNode(const osg::CameraNode* camera) { _camera = camera; } - const osg::CameraNode* getCameraNode() const { return _camera; } - - void setTexture(osg::Texture* texture, unsigned int level = 0, unsigned int face=0) { _texture = texture; _level = level; _face = face; } - osg::Texture* getTexture() { return _texture.get(); } - - void setImage(osg::Image* image) { _image = image; } - osg::Image* getImage() { return _image.get(); } - - void setImageReadPixelFormat(GLenum format) { _imageReadPixelFormat = format; } - GLenum getImageReadPixelFormat() const { return _imageReadPixelFormat; } - - void setImageReadPixelDataType(GLenum type) { _imageReadPixelDataType = type; } - GLenum getImageReadPixelDataType() const { return _imageReadPixelDataType; } - - - void setFrameBufferObject(osg::FrameBufferObject* fbo) { _fbo = fbo; } - osg::FrameBufferObject* getFrameBufferObject() { return _fbo.get(); } - const osg::FrameBufferObject* getFrameBufferObject() const { return _fbo.get(); } - - void setGraphicsContext(osg::GraphicsContext* context) { _graphicsContext = context; } - osg::GraphicsContext* getGraphicsContext() { return _graphicsContext.get(); } - const osg::GraphicsContext* getGraphicsContext() const { return _graphicsContext.get(); } - - virtual void draw(osg::State& state,RenderLeaf*& previous); - - public: - - - protected: - - virtual ~RenderToTextureStage(); - - const osg::CameraNode* _camera; - - osg::ref_ptr _texture; - unsigned int _level; - unsigned int _face; - - osg::ref_ptr _image; - GLenum _imageReadPixelFormat; - GLenum _imageReadPixelDataType; - - osg::ref_ptr _fbo; - osg::ref_ptr _graphicsContext; - -}; - -} - -#endif - diff --git a/src/osg/CameraNode.cpp b/src/osg/CameraNode.cpp index 1c7d06de8..4e051559e 100644 --- a/src/osg/CameraNode.cpp +++ b/src/osg/CameraNode.cpp @@ -21,6 +21,8 @@ CameraNode::CameraNode(): _clearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT), _transformOrder(PRE_MULTIPLE), _renderOrder(POST_RENDER), + _drawBuffer(GL_NONE), + _readBuffer(GL_NONE), _renderTargetImplementation(FRAME_BUFFER) { setStateSet(new StateSet); @@ -37,6 +39,8 @@ CameraNode::CameraNode(const CameraNode& camera,const CopyOp& copyop): _projectionMatrix(camera._projectionMatrix), _viewMatrix(camera._viewMatrix), _renderOrder(camera._renderOrder), + _drawBuffer(camera._drawBuffer), + _readBuffer(camera._readBuffer), _renderTargetImplementation(camera._renderTargetImplementation), _bufferAttachmentMap(camera._bufferAttachmentMap), _postDrawCallback(camera._postDrawCallback) diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index 7765ab4cd..74289fcff 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -1066,13 +1065,40 @@ void CullVisitor::apply(osg::CameraNode& camera) } else { + // set up lighting. + // currently ignore lights in the scene graph itself.. + // will do later. + osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage(); + + // use render to texture stage. // create the render to texture stage. - osg::ref_ptr rtts = dynamic_cast(camera.getRenderingCache()); + osg::ref_ptr rtts = dynamic_cast(camera.getRenderingCache()); if (!rtts) { - rtts = new osgUtil::RenderToTextureStage; + rtts = new osgUtil::RenderStage; rtts->setCameraNode(&camera); + + if (camera.getDrawBuffer() != GL_NONE) + { + rtts->setDrawBuffer(camera.getDrawBuffer()); + } + else + { + // inherit draw buffer from above. + rtts->setDrawBuffer(previous_stage->getDrawBuffer()); + } + + if (camera.getReadBuffer() != GL_NONE) + { + rtts->setReadBuffer(camera.getReadBuffer()); + } + else + { + // inherit read buffer from above. + rtts->setReadBuffer(previous_stage->getReadBuffer()); + } + camera.setRenderingCache(rtts.get()); } else @@ -1081,10 +1107,6 @@ void CullVisitor::apply(osg::CameraNode& camera) rtts->reset(); } - // set up lighting. - // currently ignore lights in the scene graph itself.. - // will do later. - osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage(); // set up the background color and clear mask. @@ -1099,6 +1121,7 @@ void CullVisitor::apply(osg::CameraNode& camera) osg::Viewport* viewport = camera.getViewport()!=0 ? camera.getViewport() : previous_stage->getViewport(); rtts->setViewport( viewport ); + // set up to charge the same RenderStageLighting is the parent previous stage. osg::Matrix inhertiedMVtolocalMV; inhertiedMVtolocalMV.invert(originalModelView); @@ -1176,6 +1199,9 @@ void CullVisitor::apply(osg::CameraNode& camera) fbo = new osg::FrameBufferObject; rtts->setFrameBufferObject(fbo.get()); + rtts->setDrawBuffer(GL_BACK); + rtts->setReadBuffer(GL_BACK); + bool colorAttached = false; bool depthAttached = false; bool stencilAttached = false; @@ -1237,6 +1263,9 @@ void CullVisitor::apply(osg::CameraNode& camera) traits->_doubleBuffer = (camera.getRenderTargetImplmentation()==osg::CameraNode::SEPERATE_WINDOW); + rtts->setDrawBuffer(GL_FRONT); + rtts->setReadBuffer(GL_FRONT); + bool colorAttached = false; bool depthAttached = false; bool stencilAttached = false; diff --git a/src/osgUtil/GNUmakefile b/src/osgUtil/GNUmakefile index 2c9047cf6..105bd4cb1 100644 --- a/src/osgUtil/GNUmakefile +++ b/src/osgUtil/GNUmakefile @@ -17,7 +17,6 @@ CXXFILES = \ RenderLeaf.cpp\ RenderStage.cpp\ RenderStageLighting.cpp\ - RenderToTextureStage.cpp\ SceneView.cpp\ Simplifier.cpp\ SmoothingVisitor.cpp\ diff --git a/src/osgUtil/RenderStage.cpp b/src/osgUtil/RenderStage.cpp index 12b1885e6..8aa51bfc5 100644 --- a/src/osgUtil/RenderStage.cpp +++ b/src/osgUtil/RenderStage.cpp @@ -11,7 +11,14 @@ * OpenSceneGraph Public License for more details. */ #include + #include +#include +#include +#include +#include +#include + #include #include @@ -31,11 +38,21 @@ RenderStage::RenderStage(): _stage = this; _stageDrawnThisFrame = false; + _drawBuffer = GL_NONE; + _readBuffer = GL_NONE; _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); _clearDepth = 1.0; _clearStencil = 0; + + _camera = 0; + + _level = 0; + _face = 0; + + _imageReadPixelFormat = GL_RGBA; + _imageReadPixelDataType = GL_UNSIGNED_BYTE; } RenderStage::RenderStage(SortMode mode): @@ -46,11 +63,21 @@ RenderStage::RenderStage(SortMode mode): _stage = this; _stageDrawnThisFrame = false; + _drawBuffer = GL_NONE; + _readBuffer = GL_NONE; _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); _clearDepth = 1.0; _clearStencil = 0; + + _camera = 0; + + _level = 0; + _face = 0; + + _imageReadPixelFormat = GL_RGBA; + _imageReadPixelDataType = GL_UNSIGNED_BYTE; } RenderStage::RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop): @@ -59,14 +86,20 @@ RenderStage::RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop): _preRenderList(rhs._preRenderList), _postRenderList(rhs._postRenderList), _viewport(rhs._viewport), + _drawBuffer(rhs._drawBuffer), + _readBuffer(rhs._readBuffer), _clearMask(rhs._clearMask), _colorMask(rhs._colorMask), _clearColor(rhs._clearColor), _clearAccum(rhs._clearAccum), _clearDepth(rhs._clearDepth), _clearStencil(rhs._clearStencil), + _camera(rhs._camera), + _level(rhs._level), + _face(rhs._face), + _imageReadPixelFormat(rhs._imageReadPixelFormat), + _imageReadPixelDataType(rhs._imageReadPixelDataType), _renderStageLighting(rhs._renderStageLighting) - { _stage = this; } @@ -119,9 +152,134 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous) // note, SceneView does call to drawPreRenderStages explicitly // so there is no need to call it here. drawPreRenderStages(state,previous); + + osg::State* useState = &state; + osg::GraphicsContext* callingContext = state.getGraphicsContext(); + osg::GraphicsContext* useContext = callingContext; + + if (_graphicsContext.valid() && _graphicsContext != callingContext) + { + useState = _graphicsContext->getState(); + useContext = _graphicsContext.get(); + useContext->makeCurrent(); + } + + if (_drawBuffer != GL_NONE) + { + glDrawBuffer(_drawBuffer); + } + + if (_readBuffer != GL_NONE) + { + glReadBuffer(_readBuffer); + } + + osg::FBOExtensions* fbo_ext = _fbo.valid() ? osg::FBOExtensions::instance(state.getContextID()) : 0; + bool fbo_supported = fbo_ext && fbo_ext->isSupported(); + + if (fbo_supported) + { + _fbo->apply(*useState); + } + + + // do the drawing itself. RenderBin::draw(state,previous); + + // now copy the rendered image to attached texture. + if (_texture.valid() && !fbo_supported) + { + if (callingContext && useContext!= callingContext) + { + // make the calling context use the pbuffer context for reading. + callingContext->makeContextCurrent(useContext); + + if (_readBuffer != GL_NONE) + { + glReadBuffer(_readBuffer); + } + } + + // need to implement texture cube map etc... + osg::Texture1D* texture1D = 0; + osg::Texture2D* texture2D = 0; + osg::Texture3D* texture3D = 0; + osg::TextureRectangle* textureRec = 0; + osg::TextureCubeMap* textureCubeMap = 0; + + if ((texture2D = dynamic_cast(_texture.get())) != 0) + { + texture2D->copyTexImage2D(state,_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height()); + } + else if ((textureRec = dynamic_cast(_texture.get())) != 0) + { + textureRec->copyTexImage2D(state,_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height()); + } + else if ((texture1D = dynamic_cast(_texture.get())) != 0) + { + // need to implement + texture1D->copyTexImage1D(state,_viewport->x(),_viewport->y(),_viewport->width()); + } + else if ((texture3D = dynamic_cast(_texture.get())) != 0) + { + // need to implement + texture3D->copyTexSubImage3D(state, 0, 0, _face, _viewport->x(), _viewport->y(), _viewport->width(), _viewport->height()); + } + else if ((textureCubeMap = dynamic_cast(_texture.get())) != 0) + { + // need to implement + textureCubeMap->copyTexSubImageCubeMap(state, _face, 0, 0, _viewport->x(),_viewport->y(),_viewport->width(),_viewport->height()); + } + } + + if (_image.valid()) + { + + if (_readBuffer != GL_NONE) + { + glReadBuffer(_readBuffer); + } + + _image->readPixels(_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height(),_imageReadPixelFormat,_imageReadPixelDataType); + } + + + if (_camera && _camera->getPostDrawCallback()) + { + // if we have a camera with a post draw callback invoke it. + (*(_camera->getPostDrawCallback()))(*_camera); + } + + if (fbo_supported) + { + // switch of the frame buffer object + fbo_ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + + if (fbo_supported && _camera) + { + // now generate mipmaps if they are required. + const osg::CameraNode::BufferAttachmentMap& bufferAttachements = _camera->getBufferAttachmentMap(); + for(osg::CameraNode::BufferAttachmentMap::const_iterator itr = bufferAttachements.begin(); + itr != bufferAttachements.end(); + ++itr) + { + if (itr->second._texture.valid() && itr->second._mipMapGeneration) + { + itr->second._texture->apply(*useState); + // fbo_ext->glGenerateMipmapEXT(itr->second._texture->getTextureTarget()); + } + } + } + + if (callingContext && useContext != callingContext) + { + // restore the graphics context. + callingContext->makeCurrent(); + } + // place the post draw here temprorarily while we figure out how // best to do SceneView. drawPostRenderStages(state,previous); @@ -135,8 +293,7 @@ void RenderStage::drawImplementation(osg::State& state,RenderLeaf*& previous) notify(FATAL) << "Error: cannot draw stage due to undefined viewport."<< std::endl; return; } - - + // set up the back buffer. state.applyAttribute(_viewport.get()); diff --git a/src/osgUtil/RenderToTextureStage.cpp b/src/osgUtil/RenderToTextureStage.cpp deleted file mode 100644 index d8bb748d2..000000000 --- a/src/osgUtil/RenderToTextureStage.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield - * - * This library is open source and may be redistributed and/or modified under - * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or - * (at your option) any later version. The full license is in LICENSE file - * included with this distribution, and on the openscenegraph.org website. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * OpenSceneGraph Public License for more details. -*/ -#include -#include -#include -#include -#include -#include -#include - -using namespace osg; -using namespace osgUtil; - -// register a RenderToTextureStage prototype with the RenderBin prototype list. -//RegisterRenderBinProxy s_registerRenderToTextureStageProxy; - -RenderToTextureStage::RenderToTextureStage() -{ - _camera = 0; - - _level = 0; - _face = 0; - - _imageReadPixelFormat = GL_RGBA; - _imageReadPixelDataType = GL_UNSIGNED_BYTE; -} - -RenderToTextureStage::~RenderToTextureStage() -{ -} - -void RenderToTextureStage::reset() -{ - RenderStage::reset(); -} - - -void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous) -{ - - if (_stageDrawnThisFrame) return; - - //cout << "begining RTTS draw "<x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<getState(); - useContext = _graphicsContext.get(); - useContext->makeCurrent(); - - glDrawBuffer(GL_FRONT); - glReadBuffer(GL_FRONT); - - } - - osg::FBOExtensions* fbo_ext = _fbo.valid() ? osg::FBOExtensions::instance(state.getContextID()) : 0; - bool fbo_supported = fbo_ext && fbo_ext->isSupported(); - - if (fbo_supported) - { - _fbo->apply(*useState); - } - - // do the actual rendering of the scene. - RenderStage::draw(*useState,previous); - - // now copy the rendered image to attached texture. - if (_texture.valid() && !fbo_supported) - { - if (callingContext && useContext!= callingContext) - { - // make the calling context use the pbuffer context for reading. - callingContext->makeContextCurrent(useContext); - - glReadBuffer(GL_FRONT); - } - - // need to implement texture cube map etc... - osg::Texture1D* texture1D = 0; - osg::Texture2D* texture2D = 0; - osg::Texture3D* texture3D = 0; - osg::TextureRectangle* textureRec = 0; - osg::TextureCubeMap* textureCubeMap = 0; - - if ((texture2D = dynamic_cast(_texture.get())) != 0) - { - texture2D->copyTexImage2D(state,_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height()); - } - else if ((textureRec = dynamic_cast(_texture.get())) != 0) - { - textureRec->copyTexImage2D(state,_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height()); - } - else if ((texture1D = dynamic_cast(_texture.get())) != 0) - { - // need to implement - texture1D->copyTexImage1D(state,_viewport->x(),_viewport->y(),_viewport->width()); - } - else if ((texture3D = dynamic_cast(_texture.get())) != 0) - { - // need to implement - texture3D->copyTexSubImage3D(state, 0, 0, _face, _viewport->x(), _viewport->y(), _viewport->width(), _viewport->height()); - } - else if ((textureCubeMap = dynamic_cast(_texture.get())) != 0) - { - // need to implement - textureCubeMap->copyTexSubImageCubeMap(state, _face, 0, 0, _viewport->x(),_viewport->y(),_viewport->width(),_viewport->height()); - } - } - - if (_image.valid()) - { - _image->readPixels(_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height(),_imageReadPixelFormat,_imageReadPixelDataType); - } - - - if (_camera && _camera->getPostDrawCallback()) - { - // if we have a camera with a post draw callback invoke it. - (*(_camera->getPostDrawCallback()))(*_camera); - } - - if (fbo_supported) - { - // switch of the frame buffer object - fbo_ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - } - - if (fbo_supported && _camera) - { - // now generate mipmaps if they are required. - const osg::CameraNode::BufferAttachmentMap& bufferAttachements = _camera->getBufferAttachmentMap(); - for(osg::CameraNode::BufferAttachmentMap::const_iterator itr = bufferAttachements.begin(); - itr != bufferAttachements.end(); - ++itr) - { - if (itr->second._texture.valid() && itr->second._mipMapGeneration) - { - itr->second._texture->apply(*useState); - // fbo_ext->glGenerateMipmapEXT(itr->second._texture->getTextureTarget()); - } - } - } - - if (callingContext && useContext != callingContext) - { - // restore the graphics context. - callingContext->makeCurrent(); - - glReadBuffer(GL_BACK); - } -} - diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index a08897c4c..b7faa9cf3 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -717,15 +717,16 @@ void SceneView::draw() _renderStageLeft->setColorMask(cmask); _renderStageRight->setColorMask(cmask); + _renderStageLeft->setDrawBuffer(GL_BACK_LEFT); + _renderStageLeft->setReadBuffer(GL_BACK_LEFT); + _renderStageRight->setDrawBuffer(GL_BACK_RIGHT); + _renderStageRight->setReadBuffer(GL_BACK_RIGHT); + _renderStageLeft->drawPreRenderStages(*_state,previous); _renderStageRight->drawPreRenderStages(*_state,previous); - glDrawBuffer(GL_BACK_LEFT); - glReadBuffer(GL_BACK_LEFT); _renderStageLeft->draw(*_state,previous); - glDrawBuffer(GL_BACK_RIGHT); - glReadBuffer(GL_BACK_RIGHT); _renderStageRight->draw(*_state,previous); } @@ -734,12 +735,16 @@ void SceneView::draw() { if( _drawBufferValue != GL_NONE) { - glDrawBuffer(_drawBufferValue); - glReadBuffer(_drawBufferValue); + _renderStageLeft->setDrawBuffer(_drawBufferValue); + _renderStageLeft->setReadBuffer(_drawBufferValue); + + _renderStageRight->setDrawBuffer(_drawBufferValue); + _renderStageRight->setReadBuffer(_drawBufferValue); } _localStateSet->setAttribute(_viewport.get()); + _renderStageLeft->drawPreRenderStages(*_state,previous); _renderStageRight->drawPreRenderStages(*_state,previous); @@ -791,8 +796,11 @@ void SceneView::draw() { if( _drawBufferValue != GL_NONE) { - glDrawBuffer(_drawBufferValue); - glReadBuffer(_drawBufferValue); + _renderStageLeft->setDrawBuffer(_drawBufferValue); + _renderStageLeft->setReadBuffer(_drawBufferValue); + + _renderStageRight->setDrawBuffer(_drawBufferValue); + _renderStageRight->setReadBuffer(_drawBufferValue); } // ensure that all color planes are active. @@ -854,8 +862,11 @@ void SceneView::draw() { if( _drawBufferValue != GL_NONE) { - glDrawBuffer(_drawBufferValue); - glReadBuffer(_drawBufferValue); + _renderStageLeft->setDrawBuffer(_drawBufferValue); + _renderStageLeft->setReadBuffer(_drawBufferValue); + + _renderStageRight->setDrawBuffer(_drawBufferValue); + _renderStageRight->setReadBuffer(_drawBufferValue); } // ensure that all color planes are active. @@ -916,8 +927,8 @@ void SceneView::draw() { if( _drawBufferValue != GL_NONE) { - glDrawBuffer(_drawBufferValue); - glReadBuffer(_drawBufferValue); + _renderStage->setDrawBuffer(_drawBufferValue); + _renderStage->setReadBuffer(_drawBufferValue); } // ensure that all color planes are active. @@ -952,8 +963,8 @@ void SceneView::draw() // Need to restore draw buffer when toggling Stereo off. if( _drawBufferValue != GL_NONE) { - glDrawBuffer(_drawBufferValue); - glReadBuffer(_drawBufferValue); + _renderStage->setDrawBuffer(_drawBufferValue); + _renderStage->setReadBuffer(_drawBufferValue); } _localStateSet->setAttribute(_viewport.get());