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.
This commit is contained in:
Robert Osfield 2010-01-07 12:14:47 +00:00
parent e12bce86e7
commit 47af634399
12 changed files with 87 additions and 76 deletions

View File

@ -19,6 +19,7 @@
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/FrameStamp>
#include <osg/StateAttribute>
#include <string>
#include <vector>
@ -320,9 +321,22 @@ class OSG_EXPORT Image : public BufferData
/** Get the const PixelBufferObject.*/
const PixelBufferObject* getPixelBufferObject() const { return dynamic_cast<const PixelBufferObject*>(_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; }

View File

@ -16,7 +16,6 @@
#include <OpenThreads/Mutex>
#include <osg/ImageStream>
#include <osg/StateAttribute>
#include <list>
#include <set>
@ -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() {}

View File

@ -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::"<<texture<<std::endl;
if (texture)
{
for(unsigned int i=0; i<texture->getNumImages(); ++i)
{
texture->getImage(i)->update(nv);
}
}
}
Image::Image()
:BufferData(),
_fileName(""),

View File

@ -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::"<<texture<<std::endl;
if (texture)
{
for(unsigned int i=0; i<texture->getNumImages(); ++i)
{
texture->getImage(i)->update(nv);
}
}
}
ImageSequence::ImageSequence()
{
_referenceTime = DBL_MAX;

View File

@ -12,7 +12,6 @@
*/
#include <osg/GLExtensions>
#include <osg/Texture1D>
#include <osg/ImageSequence>
#include <osg/State>
#include <osg/GLU>
@ -97,7 +96,7 @@ void Texture1D::setImage(Image* image)
{
if (_image == image) return;
if (dynamic_cast<osg::ImageSequence*>(_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<osg::ImageSequence*>(_image.get()))
if (_image.valid() && _image->requiresUpdateCall())
{
setUpdateCallback(new ImageSequence::UpdateCallback());
setUpdateCallback(new Image::UpdateCallback());
setDataVariance(osg::Object::DYNAMIC);
}
}

View File

@ -13,7 +13,6 @@
#include <osg/GLExtensions>
#include <osg/Texture2D>
#include <osg/ImageSequence>
#include <osg/State>
#include <osg/Notify>
@ -110,7 +109,7 @@ void Texture2D::setImage(Image* image)
{
if (_image == image) return;
if (dynamic_cast<osg::ImageSequence*>(_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<osg::ImageSequence*>(_image.get()))
if (_image.valid() && _image->requiresUpdateCall())
{
setUpdateCallback(new ImageSequence::UpdateCallback());
setUpdateCallback(new Image::UpdateCallback());
setDataVariance(osg::Object::DYNAMIC);
}
}

View File

@ -13,7 +13,6 @@
#include <osg/GLExtensions>
#include <osg/Texture2DArray>
#include <osg/State>
#include <osg/ImageSequence>
#include <osg/Notify>
#include <string.h>
@ -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<getNumImages(); ++i)
{
osg::ImageSequence* is = dynamic_cast<osg::ImageSequence*>(_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<getNumImages(); ++i)
{
osg::ImageSequence* is = dynamic_cast<osg::ImageSequence*>(_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);
}
}

View File

@ -13,7 +13,6 @@
#include <osg/GLExtensions>
#include <osg/Texture3D>
#include <osg/State>
#include <osg/ImageSequence>
#include <osg/GLU>
#include <osg/Notify>
@ -109,7 +108,7 @@ void Texture3D::setImage(Image* image)
{
if (_image == image) return;
if (dynamic_cast<osg::ImageSequence*>(_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<osg::ImageSequence*>(_image.get()))
if (_image.valid() && _image->requiresUpdateCall())
{
setUpdateCallback(new ImageSequence::UpdateCallback());
setUpdateCallback(new Image::UpdateCallback());
setDataVariance(osg::Object::DYNAMIC);
}
}

View File

@ -15,7 +15,6 @@
#include <osg/Image>
#include <osg/State>
#include <osg/TextureCubeMap>
#include <osg/ImageSequence>
#include <osg/Notify>
#include <osg/GLU>
@ -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<getNumImages(); ++i)
{
osg::ImageSequence* is = dynamic_cast<osg::ImageSequence*>(_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<getNumImages(); ++i)
{
osg::ImageSequence* is = dynamic_cast<osg::ImageSequence*>(_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);
}
}

View File

@ -13,7 +13,6 @@
#include <osg/GLExtensions>
#include <osg/TextureRectangle>
#include <osg/ImageSequence>
#include <osg/State>
#include <osg/GLU>
#include <osg/Notify>
@ -126,7 +125,7 @@ void TextureRectangle::setImage(Image* image)
{
if (_image == image) return;
if (dynamic_cast<osg::ImageSequence*>(_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<osg::ImageSequence*>(_image.get()))
if (_image.valid() && _image->requiresUpdateCall())
{
setUpdateCallback(new ImageSequence::UpdateCallback());
setUpdateCallback(new Image::UpdateCallback());
setDataVariance(osg::Object::DYNAMIC);
}
}

View File

@ -16,6 +16,7 @@
#include <osg/Image>
#include <osg/NodeVisitor>
#include <osg/Object>
#include <osg/StateAttribute>
#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>
@ -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 >)

View File

@ -15,7 +15,6 @@
#include <osg/ImageSequence>
#include <osg/NodeVisitor>
#include <osg/Object>
#include <osg/StateAttribute>
// 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,