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:
parent
e12bce86e7
commit
47af634399
@ -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; }
|
||||
|
||||
|
@ -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() {}
|
||||
|
@ -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(""),
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 >)
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user