From f86c82427564e490afd7b0d151d725b3c97d05b0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 25 Aug 2006 16:30:23 +0000 Subject: [PATCH] Further work on new TextureAtlasBuilder. --- include/osgUtil/Optimizer | 3 +- src/osgUtil/Optimizer.cpp | 77 +++++++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 3b177553e..5eab6de0d 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -636,6 +636,7 @@ class OSGUTIL_EXPORT Optimizer osg::ref_ptr _image; osg::ref_ptr _texture; + bool suitableForAtlas(unsigned int maximumAtlasWidth, unsigned int maximumAtlasHeight, unsigned int margin); osg::Matrix computeTextureMatrix() const; @@ -687,7 +688,7 @@ class OSGUTIL_EXPORT Optimizer Source* getSource(const osg::Texture2D* texture); SourceList _sourceList; - AtlasList _atasList; + AtlasList _atlasList; }; }; diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 5f54bca4b..c0ad89614 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -2985,6 +2985,33 @@ void Optimizer::TextureAtlasBuilder::addSource(const osg::Texture2D* texture) void Optimizer::TextureAtlasBuilder::buildAtlas() { + for(SourceList::iterator sitr = _sourceList.begin(); + sitr != _sourceList.end(); + ++sitr) + { + Source* source = sitr->get(); + if (source->suitableForAtlas(_maximumAtlasWidth,_maximumAtlasHeight,_margin)) + { + bool addedSourceToAtlas = false; + for(AtlasList::iterator aitr = _atlasList.begin(); + aitr != _atlasList.end() || addedSourceToAtlas; + ++aitr) + { + if ((*aitr)->doesSourceFit(source)) + { + (*aitr)->addSource(source); + } + } + + if (!addedSourceToAtlas) + { + osg::ref_ptr atlas = new Atlas(_maximumAtlasWidth,_maximumAtlasHeight,_margin); + _atlasList.push_back(atlas.get()); + + atlas->addSource(source); + } + } + } } osg::Image* Optimizer::TextureAtlasBuilder::getImageAtlas(unsigned int i) @@ -3069,6 +3096,41 @@ Optimizer::TextureAtlasBuilder::Source* Optimizer::TextureAtlasBuilder::getSourc return 0; } +bool Optimizer::TextureAtlasBuilder::Source::suitableForAtlas(unsigned int maximumAtlasWidth, unsigned int maximumAtlasHeight, unsigned int margin) +{ + if (!_image) return false; + + // size too big? + if (_image->s()+margin*2 > maximumAtlasWidth) return false; + if (_image->t()+margin*2 > maximumAtlasHeight) return false; + + // FIXME need to handle compressed textures... + + if (_texture.valid()) + { + if (_texture->getWrap(osg::Texture2D::WRAP_S)==osg::Texture2D::REPEAT || + _texture->getWrap(osg::Texture2D::WRAP_S)==osg::Texture2D::MIRROR) + { + // can't support repeating textures in texture atlas + return false; + } + + if (_texture->getWrap(osg::Texture2D::WRAP_T)==osg::Texture2D::REPEAT || + _texture->getWrap(osg::Texture2D::WRAP_T)==osg::Texture2D::MIRROR) + { + // can't support repeating textures in texture atlas + return false; + } + + if (_texture->getReadPBuffer()!=0) + { + // pbuffer textures not suitable + return false; + } + } + return true; +} + osg::Matrix Optimizer::TextureAtlasBuilder::Source::computeTextureMatrix() const { return osg::Matrix(); @@ -3104,6 +3166,12 @@ bool Optimizer::TextureAtlasBuilder::Atlas::doesSourceFit(Source* source) return false; } + if (sourceTexture->getReadPBuffer()!=0) + { + // pbuffer textures not suitable + return false; + } + if (_texture.valid()) { @@ -3155,7 +3223,6 @@ bool Optimizer::TextureAtlasBuilder::Atlas::doesSourceFit(Source* source) return false; } - if (_texture->getShadowTextureMode() != sourceTexture->getShadowTextureMode()) { // shadow texture mode inconsitent @@ -3167,12 +3234,6 @@ bool Optimizer::TextureAtlasBuilder::Atlas::doesSourceFit(Source* source) // shadow ambient inconsitent return false; } - - if (sourceTexture->getReadPBuffer()!=0) - { - // pbuffer textures not suitable - return false; - } } } @@ -3315,7 +3376,7 @@ void Optimizer::TextureAtlasBuilder::Atlas::copySources() itr !=_sourceList.end(); ++itr) { - osg::notify(osg::NOTICE)<<"Copying image "<_image->getFileName()<<" to "<_x<<" ,"<_y<_image->getFileName()<<" to "<<(*itr)->_x<<" ,"<<(*itr)->_y<