diff --git a/include/osg/ImageSequence b/include/osg/ImageSequence index a16fef3ab..a59c91d98 100644 --- a/include/osg/ImageSequence +++ b/include/osg/ImageSequence @@ -58,8 +58,15 @@ class OSG_EXPORT ImageSequence : public ImageStream bool getPruneOldImages() const { return _pruneOldImages; } void addImageFile(const std::string& fileName); + + FileNames& getFileNames() { return _fileNames; } + const FileNames& getFileNames() const { return _fileNames; } void addImage(osg::Image* image); + + Images& getImages() { return _images; } + const Images& getImages() const { return _images; } + virtual void update(NodeVisitor* nv); diff --git a/include/osg/StateAttribute b/include/osg/StateAttribute index ab7775a53..d7c4f23a0 100644 --- a/include/osg/StateAttribute +++ b/include/osg/StateAttribute @@ -35,6 +35,7 @@ namespace osg { class NodeVisitor; class State; class StateSet; +class Texture; /** META_StateAttribute macro define the standard clone, isSameKindAs, * className and getType methods. @@ -209,6 +210,14 @@ class OSG_EXPORT StateAttribute : public Object /** Return the name of the attribute's class type.*/ virtual const char* className() const { return "StateAttribute"; } + + /** Fast alternative to dynamic_cast<> for determining if state attribute is a Texture.*/ + virtual Texture* asTexture() { return 0; } + + /** Fast alternative to dynamic_cast<> for determining if state attribute is a Texture.*/ + virtual const Texture* asTexture() const { return 0; } + + /** Return the Type identifier of the attribute's class type.*/ virtual Type getType() const = 0; diff --git a/include/osg/Texture b/include/osg/Texture index 026af6f8d..986d375d2 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -282,11 +282,17 @@ class OSG_EXPORT Texture : public osg::StateAttribute virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } virtual const char* libraryName() const { return "osg"; } virtual const char* className() const { return "Texture"; } + + /** Fast alternative to dynamic_cast<> for determining if state attribute is a Texture.*/ + virtual Texture* asTexture() { return this; } + + /** Fast alternative to dynamic_cast<> for determining if state attribute is a Texture.*/ + virtual const Texture* asTexture() const { return this; } + virtual Type getType() const { return TEXTURE; } virtual bool isTextureAttribute() const { return true; } - virtual GLenum getTextureTarget() const = 0; virtual bool getModeUsage(StateAttribute::ModeUsage& usage) const diff --git a/src/osg/ImageSequence.cpp b/src/osg/ImageSequence.cpp index 15b3b5b6d..591c4d2a5 100644 --- a/src/osg/ImageSequence.cpp +++ b/src/osg/ImageSequence.cpp @@ -24,11 +24,15 @@ using namespace osg; void ImageSequence::UpdateCallback::operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv) { - const osg::FrameStamp* fs = nv!=0 ? nv->getFrameStamp() : 0; - osg::Texture2D* texture2D = dynamic_cast(attr); - if (texture2D && texture2D->getImage() && fs) + osg::Texture* texture = attr ? attr->asTexture() : 0; + + //osg::notify(osg::NOTICE)<<"ImageSequence::UpdateCallback::"<getImage()->update(nv); + for(unsigned int i=0; igetNumImages(); ++i) + { + texture->getImage(i)->update(nv); + } } } diff --git a/src/osg/Texture1D.cpp b/src/osg/Texture1D.cpp index 99bd15364..73622a6aa 100644 --- a/src/osg/Texture1D.cpp +++ b/src/osg/Texture1D.cpp @@ -12,6 +12,7 @@ */ #include #include +#include #include #include @@ -87,12 +88,25 @@ int Texture1D::compare(const StateAttribute& sa) const void Texture1D::setImage(Image* image) { + if (_image == image) return; + + if (dynamic_cast(_image.get())) + { + setUpdateCallback(0); + setDataVariance(osg::Object::STATIC); + } + // delete old texture objects. dirtyTextureObject(); _image = image; _modifiedCount.setAllElementsTo(0); - + + if (dynamic_cast(_image.get())) + { + setUpdateCallback(new ImageSequence::UpdateCallback()); + setDataVariance(osg::Object::DYNAMIC); + } } diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp index 96e828704..1f545e316 100644 --- a/src/osg/Texture2D.cpp +++ b/src/osg/Texture2D.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -108,8 +109,22 @@ int Texture2D::compare(const StateAttribute& sa) const void Texture2D::setImage(Image* image) { + if (_image == image) return; + + if (dynamic_cast(_image.get())) + { + setUpdateCallback(0); + setDataVariance(osg::Object::STATIC); + } + _image = image; _modifiedCount.setAllElementsTo(0); + + if (dynamic_cast(_image.get())) + { + setUpdateCallback(new ImageSequence::UpdateCallback()); + setDataVariance(osg::Object::DYNAMIC); + } } diff --git a/src/osg/Texture2DArray.cpp b/src/osg/Texture2DArray.cpp index 58d18c1a6..5e0745544 100644 --- a/src/osg/Texture2DArray.cpp +++ b/src/osg/Texture2DArray.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -110,9 +111,40 @@ void Texture2DArray::setImage(unsigned int layer, Image* image) return; } + if (_images[layer] == image) return; + + unsigned numImageSequencesBefore = 0; + for (unsigned int i=0; i(_images[i].get()); + if (is) ++numImageSequencesBefore; + } + // 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; + for (unsigned int i=0; i(_images[i].get()); + if (is) ++numImageSequencesAfter; + } + + if (numImageSequencesBefore>0) + { + if (numImageSequencesAfter==0) + { + setUpdateCallback(0); + setDataVariance(osg::Object::STATIC); + } + } + else if (numImageSequencesAfter>0) + { + setUpdateCallback(new ImageSequence::UpdateCallback()); + setDataVariance(osg::Object::DYNAMIC); + } } void Texture2DArray::setTextureSize(int width, int height, int depth) diff --git a/src/osg/Texture3D.cpp b/src/osg/Texture3D.cpp index 78060c4b4..78c268c19 100644 --- a/src/osg/Texture3D.cpp +++ b/src/osg/Texture3D.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -96,12 +97,26 @@ int Texture3D::compare(const StateAttribute& sa) const void Texture3D::setImage(Image* image) { + if (_image == image) return; + + if (dynamic_cast(_image.get())) + { + setUpdateCallback(0); + setDataVariance(osg::Object::STATIC); + } + // delete old texture objects. dirtyTextureObject(); _modifiedCount.setAllElementsTo(0); _image = image; + + if (dynamic_cast(_image.get())) + { + setUpdateCallback(new ImageSequence::UpdateCallback()); + setDataVariance(osg::Object::DYNAMIC); + } } void Texture3D::computeRequiredTextureDimensions(State& state, const osg::Image& image,GLsizei& inwidth, GLsizei& inheight,GLsizei& indepth, GLsizei& numMipmapLevels) const @@ -195,6 +210,8 @@ void Texture3D::apply(State& state) const } else if (_image.get() && getModifiedCount(contextID) != _image->getModifiedCount()) { + computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels); + applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels); // update the modified count to show that it is upto date. @@ -344,13 +361,14 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz if (!compressed_image) { - // notify(WARN)<<"glTexImage3D"<getFileName()<<"' data="<<(void*)image->data()<glTexImage3D( target, 0, _internalFormat, inwidth, inheight, indepth, _borderWidth, (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), image->data() ); + notify(WARN)<<"done glTexImage3D"<isCompressedTexImage3DSupported()) { diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index dbb9059ad..d21cce242 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -128,8 +129,40 @@ int TextureCubeMap::compare(const StateAttribute& sa) const void TextureCubeMap::setImage( unsigned int face, Image* image) { + if (_images[face] == image) return; + + unsigned numImageSequencesBefore = 0; + for (unsigned int i=0; i(_images[i].get()); + if (is) ++numImageSequencesBefore; + } + _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; + for (unsigned int i=0; i(_images[i].get()); + if (is) ++numImageSequencesAfter; + } + + if (numImageSequencesBefore>0) + { + if (numImageSequencesAfter==0) + { + setUpdateCallback(0); + setDataVariance(osg::Object::STATIC); + } + } + else if (numImageSequencesAfter>0) + { + setUpdateCallback(new ImageSequence::UpdateCallback()); + setDataVariance(osg::Object::DYNAMIC); + } } Image* TextureCubeMap::getImage(unsigned int face) diff --git a/src/osg/TextureRectangle.cpp b/src/osg/TextureRectangle.cpp index 6bc84bc39..afc1dadfb 100644 --- a/src/osg/TextureRectangle.cpp +++ b/src/osg/TextureRectangle.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -123,10 +124,24 @@ int TextureRectangle::compare(const StateAttribute& sa) const void TextureRectangle::setImage(Image* image) { + if (_image == image) return; + + if (dynamic_cast(_image.get())) + { + setUpdateCallback(0); + setDataVariance(osg::Object::STATIC); + } + // delete old texture objects. dirtyTextureObject(); _image = image; + + if (dynamic_cast(_image.get())) + { + setUpdateCallback(new ImageSequence::UpdateCallback()); + setDataVariance(osg::Object::DYNAMIC); + } }