From 47af6343997004cc6b8b43d921804199943eea35 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 7 Jan 2010 12:14:47 +0000 Subject: [PATCH] Refactored the way that osg::Image/ImageSequence manages the update callback that needs to be attached to Textures to make it possible to use the Image::update() mechansim in other subclasses from osg::Image. To enable the automatic attachment of the required update callback to call osg::Image::update(..) subclasses from osg::Image will need to implement the osg::Image::requestUpdateCall() and return true, and implement the osg::Image::update(NodeVisitor*) method to recieve the update call during the update traversal. --- include/osg/Image | 16 +++++++++++++++- include/osg/ImageSequence | 11 ++++------- src/osg/Image.cpp | 14 ++++++++++++++ src/osg/ImageSequence.cpp | 14 -------------- src/osg/Texture1D.cpp | 7 +++---- src/osg/Texture2D.cpp | 9 ++++----- src/osg/Texture2DArray.cpp | 21 +++++++++------------ src/osg/Texture3D.cpp | 9 ++++----- src/osg/TextureCubeMap.cpp | 21 +++++++++------------ src/osg/TextureRectangle.cpp | 9 ++++----- src/osgWrappers/osg/Image.cpp | 16 +++++++++++++++- src/osgWrappers/osg/ImageSequence.cpp | 16 ++++++---------- 12 files changed, 87 insertions(+), 76 deletions(-) diff --git a/include/osg/Image b/include/osg/Image index 23bbcd681..21bad3ae1 100644 --- a/include/osg/Image +++ b/include/osg/Image @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -320,9 +321,22 @@ class OSG_EXPORT Image : public BufferData /** Get the const PixelBufferObject.*/ const PixelBufferObject* getPixelBufferObject() const { return dynamic_cast(_bufferObject.get()); } - + + /** return whether the update(NodeVisitor* nv) should be required on each frame to enable proper working of osg::Image.*/ + virtual bool requiresUpdateCall() const { return false; } + + /** update method for osg::Image subclasses that update themselves during the update traversal.*/ virtual void update(NodeVisitor* /*nv*/) {} + /** convience update callback class that can be attached to StateAttribute (such as Textures) to ensure + * that the Image::update(NodeVisitor*) method is called during the update traversal. This callback + * is automatically attached when Image::requiresUpdateCall() is true (it's false by default.) + */ + struct OSG_EXPORT UpdateCallback : public osg::StateAttributeCallback + { + virtual void operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv); + }; + /** method for sending pointer events to images that are acting as front ends to interactive surfaces such as a vnc or browser window. Return true if handled. */ virtual bool sendPointerEvent(int /*x*/, int /*y*/, int /*buttonMask*/) { return false; } diff --git a/include/osg/ImageSequence b/include/osg/ImageSequence index 822bd2156..94503b741 100644 --- a/include/osg/ImageSequence +++ b/include/osg/ImageSequence @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -101,15 +100,13 @@ class OSG_EXPORT ImageSequence : public ImageStream Images& getImages() { return _images; } const Images& getImages() const { return _images; } - + /** ImageSequence requires a call to update(NodeVisitor*) during the update traversal so return true.*/ + virtual bool requiresUpdateCall() const { return true; } + + /** update method for osg::Image subclasses that update themselves during the update traversal.*/ virtual void update(NodeVisitor* nv); - struct OSG_EXPORT UpdateCallback : public osg::StateAttributeCallback - { - virtual void operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv); - }; - protected: virtual ~ImageSequence() {} diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 8bdc91124..b3a5e882b 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -63,6 +63,20 @@ using namespace osg; using namespace std; +void Image::UpdateCallback::operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv) +{ + osg::Texture* texture = attr ? attr->asTexture() : 0; + + // osg::notify(osg::NOTICE)<<"ImageSequence::UpdateCallback::"<getNumImages(); ++i) + { + texture->getImage(i)->update(nv); + } + } +} + Image::Image() :BufferData(), _fileName(""), diff --git a/src/osg/ImageSequence.cpp b/src/osg/ImageSequence.cpp index 6f0601e09..1e7aa1198 100644 --- a/src/osg/ImageSequence.cpp +++ b/src/osg/ImageSequence.cpp @@ -22,20 +22,6 @@ using namespace osg; -void ImageSequence::UpdateCallback::operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv) -{ - osg::Texture* texture = attr ? attr->asTexture() : 0; - - // osg::notify(osg::NOTICE)<<"ImageSequence::UpdateCallback::"<getNumImages(); ++i) - { - texture->getImage(i)->update(nv); - } - } -} - ImageSequence::ImageSequence() { _referenceTime = DBL_MAX; diff --git a/src/osg/Texture1D.cpp b/src/osg/Texture1D.cpp index e6eb7df4d..db3b01069 100644 --- a/src/osg/Texture1D.cpp +++ b/src/osg/Texture1D.cpp @@ -12,7 +12,6 @@ */ #include #include -#include #include #include @@ -97,7 +96,7 @@ void Texture1D::setImage(Image* image) { if (_image == image) return; - if (dynamic_cast(_image.get())) + if (_image.valid() && _image->requiresUpdateCall()) { setUpdateCallback(0); setDataVariance(osg::Object::STATIC); @@ -109,9 +108,9 @@ void Texture1D::setImage(Image* image) _image = image; _modifiedCount.setAllElementsTo(0); - if (dynamic_cast(_image.get())) + if (_image.valid() && _image->requiresUpdateCall()) { - setUpdateCallback(new ImageSequence::UpdateCallback()); + setUpdateCallback(new Image::UpdateCallback()); setDataVariance(osg::Object::DYNAMIC); } } diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp index 8d8455f53..e23540fe4 100644 --- a/src/osg/Texture2D.cpp +++ b/src/osg/Texture2D.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -110,7 +109,7 @@ void Texture2D::setImage(Image* image) { if (_image == image) return; - if (dynamic_cast(_image.get())) + if (_image.valid() && _image->requiresUpdateCall()) { setUpdateCallback(0); setDataVariance(osg::Object::STATIC); @@ -118,10 +117,10 @@ void Texture2D::setImage(Image* image) _image = image; _modifiedCount.setAllElementsTo(0); - - if (dynamic_cast(_image.get())) + + if (_image.valid() && _image->requiresUpdateCall()) { - setUpdateCallback(new ImageSequence::UpdateCallback()); + setUpdateCallback(new Image::UpdateCallback()); setDataVariance(osg::Object::DYNAMIC); } } diff --git a/src/osg/Texture2DArray.cpp b/src/osg/Texture2DArray.cpp index 7b00453a1..ea9073711 100644 --- a/src/osg/Texture2DArray.cpp +++ b/src/osg/Texture2DArray.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -113,36 +112,34 @@ void Texture2DArray::setImage(unsigned int layer, Image* image) if (_images[layer] == image) return; - unsigned numImageSequencesBefore = 0; + unsigned numImageRequireUpdateBefore = 0; for (unsigned int i=0; i(_images[i].get()); - if (is) ++numImageSequencesBefore; + if (_images[i].valid() && _images[i]->requiresUpdateCall()) ++numImageRequireUpdateBefore; } // set image _images[layer] = image; _modifiedCount[layer].setAllElementsTo(0); - // find out if we need to reset the update callback to handle the animation of ImageSequence - unsigned numImageSequencesAfter = 0; + // find out if we need to reset the update callback to handle the animation of image + unsigned numImageRequireUpdateAfter = 0; for (unsigned int i=0; i(_images[i].get()); - if (is) ++numImageSequencesAfter; + if (_images[i].valid() && _images[i]->requiresUpdateCall()) ++numImageRequireUpdateAfter; } - if (numImageSequencesBefore>0) + if (numImageRequireUpdateBefore>0) { - if (numImageSequencesAfter==0) + if (numImageRequireUpdateAfter==0) { setUpdateCallback(0); setDataVariance(osg::Object::STATIC); } } - else if (numImageSequencesAfter>0) + else if (numImageRequireUpdateAfter>0) { - setUpdateCallback(new ImageSequence::UpdateCallback()); + setUpdateCallback(new Image::UpdateCallback()); setDataVariance(osg::Object::DYNAMIC); } } diff --git a/src/osg/Texture3D.cpp b/src/osg/Texture3D.cpp index f46c2dcb4..303c31d9c 100644 --- a/src/osg/Texture3D.cpp +++ b/src/osg/Texture3D.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -109,7 +108,7 @@ void Texture3D::setImage(Image* image) { if (_image == image) return; - if (dynamic_cast(_image.get())) + if (_image.valid() && _image->requiresUpdateCall()) { setUpdateCallback(0); setDataVariance(osg::Object::STATIC); @@ -121,10 +120,10 @@ void Texture3D::setImage(Image* image) _modifiedCount.setAllElementsTo(0); _image = image; - - if (dynamic_cast(_image.get())) + + if (_image.valid() && _image->requiresUpdateCall()) { - setUpdateCallback(new ImageSequence::UpdateCallback()); + setUpdateCallback(new Image::UpdateCallback()); setDataVariance(osg::Object::DYNAMIC); } } diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index 666185905..97f181cb7 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -131,36 +130,34 @@ void TextureCubeMap::setImage( unsigned int face, Image* image) { if (_images[face] == image) return; - unsigned numImageSequencesBefore = 0; + unsigned numImageRequireUpdateBefore = 0; for (unsigned int i=0; i(_images[i].get()); - if (is) ++numImageSequencesBefore; + if (_images[i].valid() && _images[i]->requiresUpdateCall()) ++numImageRequireUpdateBefore; } _images[face] = image; _modifiedCount[face].setAllElementsTo(0); - // find out if we need to reset the update callback to handle the animation of ImageSequence - unsigned numImageSequencesAfter = 0; + // find out if we need to reset the update callback to handle the animation of image + unsigned numImageRequireUpdateAfter = 0; for (unsigned int i=0; i(_images[i].get()); - if (is) ++numImageSequencesAfter; + if (_images[i].valid() && _images[i]->requiresUpdateCall()) ++numImageRequireUpdateAfter; } - if (numImageSequencesBefore>0) + if (numImageRequireUpdateBefore>0) { - if (numImageSequencesAfter==0) + if (numImageRequireUpdateAfter==0) { setUpdateCallback(0); setDataVariance(osg::Object::STATIC); } } - else if (numImageSequencesAfter>0) + else if (numImageRequireUpdateAfter>0) { - setUpdateCallback(new ImageSequence::UpdateCallback()); + setUpdateCallback(new Image::UpdateCallback()); setDataVariance(osg::Object::DYNAMIC); } } diff --git a/src/osg/TextureRectangle.cpp b/src/osg/TextureRectangle.cpp index fa44f6a1a..740c1ba8c 100644 --- a/src/osg/TextureRectangle.cpp +++ b/src/osg/TextureRectangle.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -126,7 +125,7 @@ void TextureRectangle::setImage(Image* image) { if (_image == image) return; - if (dynamic_cast(_image.get())) + if (_image.valid() && _image->requiresUpdateCall()) { setUpdateCallback(0); setDataVariance(osg::Object::STATIC); @@ -136,10 +135,10 @@ void TextureRectangle::setImage(Image* image) dirtyTextureObject(); _image = image; - - if (dynamic_cast(_image.get())) + + if (_image.valid() && _image->requiresUpdateCall()) { - setUpdateCallback(new ImageSequence::UpdateCallback()); + setUpdateCallback(new Image::UpdateCallback()); setDataVariance(osg::Object::DYNAMIC); } } diff --git a/src/osgWrappers/osg/Image.cpp b/src/osgWrappers/osg/Image.cpp index a17a918ff..b6136b0ae 100644 --- a/src/osgWrappers/osg/Image.cpp +++ b/src/osgWrappers/osg/Image.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -375,10 +376,15 @@ BEGIN_OBJECT_REFLECTOR(osg::Image) __C5_PixelBufferObject_P1__getPixelBufferObject, "Get the const PixelBufferObject. ", ""); + I_Method0(bool, requiresUpdateCall, + Properties::VIRTUAL, + __bool__requiresUpdateCall, + "return whether the update(NodeVisitor* nv) should be required on each frame to enable proper working of osg::Image. ", + ""); I_Method1(void, update, IN, osg::NodeVisitor *, x, Properties::VIRTUAL, __void__update__NodeVisitor_P1, - "", + "update method for osg::Image subclasses that update themselves during the update traversal. ", ""); I_Method3(bool, sendPointerEvent, IN, int, x, IN, int, x, IN, int, x, Properties::VIRTUAL, @@ -498,5 +504,13 @@ BEGIN_OBJECT_REFLECTOR(osg::Image) __void__setWriteHint__WriteHint); END_REFLECTOR +BEGIN_OBJECT_REFLECTOR(osg::Image::UpdateCallback) + I_DeclaringFile("osg/Image"); + I_BaseType(osg::StateAttributeCallback); + I_Constructor0(____UpdateCallback, + "", + ""); +END_REFLECTOR + STD_VECTOR_REFLECTOR(std::vector< unsigned int >) diff --git a/src/osgWrappers/osg/ImageSequence.cpp b/src/osgWrappers/osg/ImageSequence.cpp index 0a4302b58..b93081658 100644 --- a/src/osgWrappers/osg/ImageSequence.cpp +++ b/src/osgWrappers/osg/ImageSequence.cpp @@ -15,7 +15,6 @@ #include #include #include -#include // Must undefine IN and OUT macros defined in Windows headers #ifdef IN @@ -206,10 +205,15 @@ BEGIN_OBJECT_REFLECTOR(osg::ImageSequence) __C5_Images_R1__getImages, "", ""); + I_Method0(bool, requiresUpdateCall, + Properties::VIRTUAL, + __bool__requiresUpdateCall, + "ImageSequence requires a call to update(NodeVisitor*) during the update traversal so return true. ", + ""); I_Method1(void, update, IN, osg::NodeVisitor *, nv, Properties::VIRTUAL, __void__update__NodeVisitor_P1, - "", + "update method for osg::Image subclasses that update themselves during the update traversal. ", ""); I_ProtectedMethod0(void, applyLoopingMode, Properties::VIRTUAL, @@ -269,14 +273,6 @@ BEGIN_OBJECT_REFLECTOR(osg::ImageSequence) __void__setTimeMultiplier__double); END_REFLECTOR -BEGIN_OBJECT_REFLECTOR(osg::ImageSequence::UpdateCallback) - I_DeclaringFile("osg/ImageSequence"); - I_BaseType(osg::StateAttributeCallback); - I_Constructor0(____UpdateCallback, - "", - ""); -END_REFLECTOR - BEGIN_VALUE_REFLECTOR(osg::ref_ptr< osg::Image >) I_DeclaringFile("osg/ref_ptr"); I_Constructor0(____ref_ptr,