diff --git a/include/osg/CameraNode b/include/osg/CameraNode index 7802e8f0b..7064e8438 100644 --- a/include/osg/CameraNode +++ b/include/osg/CameraNode @@ -231,7 +231,7 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings void attach(BufferComponent buffer, GLenum internalFormat); - void attach(BufferComponent buffer, osg::Texture* texture, unsigned int level = 0, unsigned int face=0); + void attach(BufferComponent buffer, osg::Texture* texture, unsigned int level = 0, unsigned int face=0, bool mipMapGeneration=false); void attach(BufferComponent buffer, osg::Image* image); @@ -242,13 +242,15 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings Attachment(): _internalFormat(GL_NONE), _level(0), - _face(0) {} + _face(0), + _mipMapGeneration(false) {} GLenum _internalFormat; ref_ptr _image; ref_ptr _texture; unsigned int _level; unsigned int _face; + bool _mipMapGeneration; }; typedef std::map< BufferComponent, Attachment> BufferAttachmentMap; diff --git a/include/osg/GraphicsContext b/include/osg/GraphicsContext index ca73d0f77..59289e650 100644 --- a/include/osg/GraphicsContext +++ b/include/osg/GraphicsContext @@ -48,6 +48,7 @@ class OSG_EXPORT GraphicsContext : public Referenced _target(0), _level(0), _face(0), + _mipMapGeneration(false), _sharedContext() {} // where graphic context is be hosted. @@ -83,6 +84,7 @@ class OSG_EXPORT GraphicsContext : public Referenced GLenum _target; unsigned int _level; unsigned int _face; + unsigned int _mipMapGeneration; // shared context GraphicsContext* _sharedContext; diff --git a/src/osg/CameraNode.cpp b/src/osg/CameraNode.cpp index 81dd21487..1c7d06de8 100644 --- a/src/osg/CameraNode.cpp +++ b/src/osg/CameraNode.cpp @@ -174,11 +174,12 @@ void CameraNode::attach(BufferComponent buffer, GLenum internalFormat) _bufferAttachmentMap[buffer]._internalFormat = internalFormat; } -void CameraNode::attach(BufferComponent buffer, osg::Texture* texture, unsigned int level, unsigned int face) +void CameraNode::attach(BufferComponent buffer, osg::Texture* texture, unsigned int level, unsigned int face, bool mipMapGeneration) { _bufferAttachmentMap[buffer]._texture = texture; _bufferAttachmentMap[buffer]._level = level; _bufferAttachmentMap[buffer]._face = face; + _bufferAttachmentMap[buffer]._mipMapGeneration = mipMapGeneration; } void CameraNode::attach(BufferComponent buffer, osg::Image* image) diff --git a/src/osgProducer/GraphicsContextImplementation.cpp b/src/osgProducer/GraphicsContextImplementation.cpp index b51490903..f620f28c5 100644 --- a/src/osgProducer/GraphicsContextImplementation.cpp +++ b/src/osgProducer/GraphicsContextImplementation.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace osgProducer; @@ -56,7 +57,8 @@ GraphicsContextImplementation::GraphicsContextImplementation(Traits* traits) if (traits->_target) { - _rs->setRenderToTextureOptions(Producer::RenderSurface::RenderToTextureOptions_Default); + _rs->setRenderToTextureOptions(traits->_mipMapGeneration ? Producer::RenderSurface::RequestSpaceForMipMaps : + Producer::RenderSurface::RenderToTextureOptions_Default); _rs->setRenderToTextureMipMapLevel(traits->_level); _rs->setRenderToTextureMode(traits->_alpha>0 ? Producer::RenderSurface::RenderToRGBATexture : Producer::RenderSurface::RenderToRGBTexture); @@ -70,10 +72,12 @@ GraphicsContextImplementation::GraphicsContextImplementation(Traits* traits) _rs->setRenderToTextureTarget(Producer::RenderSurface::Texture2D); break; case(GL_TEXTURE_3D) : + osg::notify(osg::NOTICE)<<"PBuffer render to Texture3D not supported."<setRenderToTextureTarget(Producer::RenderSurface::Texture3D); break; case(GL_TEXTURE_RECTANGLE) : + osg::notify(osg::NOTICE)<<"PBuffer render to TextureRectangle not supported."<setRenderToTextureTarget(Producer::RenderSurface::TextureRectangle); break; diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index 4e189a5fb..6b6c41a75 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -1066,6 +1066,7 @@ void CullVisitor::apply(osg::CameraNode& camera) if (!rtts) { rtts = new osgUtil::RenderToTextureStage; + rtts->setCameraNode(&camera); camera.setRenderingCache(rtts.get()); } else diff --git a/src/osgUtil/RenderToTextureStage.cpp b/src/osgUtil/RenderToTextureStage.cpp index fd2c4ba54..f6d7234b4 100644 --- a/src/osgUtil/RenderToTextureStage.cpp +++ b/src/osgUtil/RenderToTextureStage.cpp @@ -43,6 +43,28 @@ void RenderToTextureStage::reset() RenderStage::reset(); } +class GenerateMipMapHelper : public StateAttribute::ModeUsage +{ + public: + GenerateMipMapHelper(osg::FBOExtensions* fbo_ext): + _fbo_ext(fbo_ext) {} + + virtual ~GenerateMipMapHelper() {} + + virtual void usesMode(StateAttribute::GLMode) + { + } + + virtual void usesTextureMode(StateAttribute::GLMode mode) + { + _fbo_ext->glGenerateMipmapEXT((GLenum)mode); + } + + osg::FBOExtensions* _fbo_ext; + +}; + + void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous) { @@ -126,6 +148,23 @@ void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous) _image->readPixels(_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height(),_imageReadPixelFormat,_imageReadPixelDataType); } + 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); + GenerateMipMapHelper generateMipMap(fbo_ext); + itr->second._texture->getModeUsage(generateMipMap); + } + } + } + if (_camera && _camera->getPostDrawCallback()) { // if we have a camera with a post draw callback invoke it.