#include<osgViewer/Viewer>
#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>
#include<osg/NodeVisitor>
#include<osgDB/ReadFile>
#include<osgDB/WriteFile>
#include<osgUtil/Optimizer>
#include<iostream>
#include<string>
#include<map>
class TextureVisitor:public osg::NodeVisitor
{
public:
TextureVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
{
}
virtual void apply(osg::Node& node)
{
if(node.getStateSet())
{
apply(node.getStateSet());
}
traverse(node);
}
virtual void apply(osg::Geode& geode)
{
if(geode.getStateSet())
{
apply(geode.getStateSet());
}
unsigned int cnt = geode.getNumDrawables();
for(unsigned int i = 0; i < cnt; i++)
{
apply(geode.getDrawable(i)->getStateSet());
}
traverse(geode);
}
void apply(osg::StateSet* state)
{
osg::StateSet::TextureAttributeList& texAttribList = state->getTextureAttributeList();
for(unsigned int i = 0; i < texAttribList.size(); i++)
{
osg::Texture2D* tex2D = NULL;
if(tex2D = dynamic_cast<osg::Texture2D*>(state->getTextureAttribute(i, osg::StateAttribute::TEXTURE)))
{
if(tex2D->getImage())
{
_imageList.insert(std::make_pair(tex2D->getImage()->getFileName(), tex2D->getImage()));
}
}
}
}
std::map<std::string, osg::Image*>& getImages(void)
{
return _imageList;
}
protected:
std::map<std::string, osg::Image*> _imageList;
};
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> root = new osg::Group();
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
TextureVisitor textureTV;
node->accept(textureTV);
std::map<std::string, osg::Image*> imageList = textureTV.getImages();
std::map<std::string, osg::Image*>::iterator iter = imageList.begin();
unsigned int cnt = 0;
char* buffer = new char[2000];
for(; iter != imageList.end(); iter++)
{
sprintf(buffer, "d:/TextureImage%d.jpg", cnt++);
osgDB::writeImageFile(*(iter->second),buffer);
}
root->addChild(node.get());
osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
return 0;
}