diff --git a/examples/osgconv/GNUmakefile b/examples/osgconv/GNUmakefile index 947448973..b67457c45 100644 --- a/examples/osgconv/GNUmakefile +++ b/examples/osgconv/GNUmakefile @@ -10,7 +10,7 @@ CXXFILES =\ HEADERFILES = \ OrientationConverter.h -LIBS += -losg -losgUtil -losgGA -losgDB $(GL_LIBS) $(OTHER_LIBS) +LIBS += -losgProducer -lProducer -losg -losgUtil -losgGA -losgDB $(GL_LIBS) $(OTHER_LIBS) INSTFILES = \ $(CXXFILES)\ diff --git a/examples/osgconv/osgconv.cpp b/examples/osgconv/osgconv.cpp index dd3702844..f7fb9bb6d 100644 --- a/examples/osgconv/osgconv.cpp +++ b/examples/osgconv/osgconv.cpp @@ -1,8 +1,12 @@ #include + +#include +#include #include #include #include #include +#include #include #include @@ -11,12 +15,15 @@ #include +#include + +#include + #include "OrientationConverter.h" #include "GeoSet.h" typedef std::vector FileNameList; -static bool do_convert = false; //////////////////////////////////////////////////////////////////////////// // Convert GeoSet To Geometry Visitor. @@ -55,16 +62,113 @@ public: }; +class GraphicsContext { + public: + GraphicsContext() + { + rs = new Producer::RenderSurface; + rs->setWindowRectangle(0,0,1,1); + rs->useBorder(false); + rs->useConfigEventThread(false); + rs->realize(); + std::cout<<"Realized window"< rs; +}; + +class CompressTexturesVisitor : public osg::NodeVisitor +{ +public: + + CompressTexturesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + + virtual void apply(osg::Node& node) + { + if (node.getStateSet()) apply(*node.getStateSet()); + traverse(node); + } + + virtual void apply(osg::Geode& node) + { + if (node.getStateSet()) apply(*node.getStateSet()); + + for(unsigned int i=0;igetStateSet()) apply(*drawable->getStateSet()); + } + + traverse(node); + } + + virtual void apply(osg::StateSet& stateset) + { + // search for the existance of any texture object attributes + for(unsigned int i=0;i(stateset.getTextureAttribute(i,osg::StateAttribute::TEXTURE)); + if (texture) + { + _textureSet.insert(texture); + } + } + } + + void compress() + { + GraphicsContext context; + + osg::ref_ptr state = new osg::State; + + for(TextureSet::iterator itr=_textureSet.begin(); + itr!=_textureSet.end(); + ++itr) + { + osg::Texture2D* texture = const_cast(itr->get()); + osg::Image* image = texture->getImage(); + if (image && + (image->getPixelFormat()==GL_RGB || image->getPixelFormat()==GL_RGBA) && + (image->s()>=32 && image->t()>=32)) + { + texture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT3_COMPRESSION); + + // get OpenGL driver to create texture from image. + texture->apply(*state); + + image->readImageFromCurrentTexture(0,true); + + texture->setInternalFormatMode(osg::Texture::USE_IMAGE_DATA_FORMAT); + } + } + } + + typedef std::set< osg::ref_ptr > TextureSet; + TextureSet _textureSet; + + +}; + + static void usage( const char *prog, const char *msg ) { - osg::notify(osg::NOTICE)<< std::endl; - osg::notify(osg::NOTICE) << msg << std::endl; + if (msg) + { + osg::notify(osg::NOTICE)<< std::endl; + osg::notify(osg::NOTICE) << msg << std::endl; + } osg::notify(osg::NOTICE)<< std::endl; osg::notify(osg::NOTICE)<<"usage:"<< std::endl; osg::notify(osg::NOTICE)<<" " << prog << " [options] infile1 [infile2 ...] outfile"<< std::endl; osg::notify(osg::NOTICE)<< std::endl; osg::notify(osg::NOTICE)<<"options:"<< std::endl; osg::notify(osg::NOTICE)<<" -O option - ReaderWriter option"<< std::endl; + osg::notify(osg::NOTICE)<<" --compress - Compress textures."<< std::endl; osg::notify(osg::NOTICE)<<" -l libraryName - load plugin of name libraryName"<< std::endl; osg::notify(osg::NOTICE)<<" i.e. -l osgdb_pfb"<< std::endl; osg::notify(osg::NOTICE)<<" Useful for loading reader/writers which can load"<< std::endl; @@ -112,177 +216,126 @@ static void usage( const char *prog, const char *msg ) << std::endl; } -static bool -parse_args( int argc, char **argv, FileNameList &fileNames, - OrientationConverter &oc, osgDB::ReaderWriter::Options* options ) -{ - int nexti; - std::string opt = ""; - - for(int i = 1; i < argc; i=nexti ) - { - nexti = i+1; - - if (argv[i][0]=='-') - { - for( unsigned int j = 1; j < strlen( argv[i] ); j++ ) - { - switch(argv[i][j]) - { - case 'O': - if (nexticreateLibraryNameForExtension(argv[nexti++]); - osgDB::Registry::instance()->loadLibrary(libName); - } - else - { - usage( argv[0], "Extension option requires an argument." ); - return false; - } - break; - - case('l'): - if (nextiloadLibrary(argv[nexti++]); - } - else - { - usage( argv[0], "Library option requires an argument." ); - return false; - } - break; - - case 'o' : - if( nexti < argc ) - { - osg::Vec3 from, to; - if( sscanf( argv[nexti], "%f,%f,%f-%f,%f,%f", - &from[0], &from[1], &from[2], - &to[0], &to[1], &to[2] ) - != 6 ) - { - float degrees; - osg::Vec3 axis; - // Try deg-axis format - if( sscanf( argv[nexti], "%f-%f,%f,%f", - °rees, &axis[0], &axis[1], &axis[2] ) != 4 ) - { - usage( argv[0], "Orientation argument format incorrect." ); - return false; - } - else - { - oc.setRotation( degrees, axis ); - do_convert = true; - } - } - else - { - oc.setRotation( from, to ); - do_convert = true; - } - } - else - { - usage( argv[0], "Orientation conversion option requires an argument." ); - return false; - } - nexti++; - break; - - case 't' : - if( nexti < argc ) - { - osg::Vec3 trans(0,0,0); - if( sscanf( argv[nexti++], "%f,%f,%f", - &trans[0], &trans[1], &trans[2] ) != 3 ) - { - usage( argv[0], "Translation argument format incorrect." ); - return false; - } - oc.setTranslation( trans ); - do_convert = true; - } - else - { - usage( argv[0], "Translation conversion option requires an argument." ); - return false; - } - break; - - case 's' : - if( nexti < argc ) - { - osg::Vec3 scale(0,0,0); - if( sscanf( argv[nexti++], "%f,%f,%f", - &scale[0], &scale[1], &scale[2] ) != 3 ) - { - usage( argv[0], "Scale argument format incorrect." ); - return false; - } - oc.setScale( scale ); - do_convert = true; - } - else - { - usage( argv[0], "Scale conversion option requires an argument." ); - return false; - } - break; - - default : - std::string a = "Invalid option " ; - a += "'"; - a += argv[i][j] ; - a += "'."; - usage( argv[0], a.c_str() ); - return false; - break; - } - } - } else - { - fileNames.push_back(argv[i]); - } - } - - if (fileNames.empty()) - { - usage( argv[0], "No files specified." ); - return false; - } - - options->setOptionString(opt); - - return true; -} int main( int argc, char **argv ) { + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + usage( arguments.getApplicationName().c_str(), 0 ); + //arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + + if (arguments.argc()<=1) + { + arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); + return 1; + } + FileNameList fileNames; OrientationConverter oc; + bool do_convert = false; + bool compressTextures = false; + + std::string str; + while (arguments.read("-O",str)) + { + osgDB::ReaderWriter::Options* options = new osgDB::ReaderWriter::Options; + options->setOptionString(str); + osgDB::Registry::instance()->setOptions(options); + } + + std::string ext; + while (arguments.read("-e",ext)) + { + std::string libName = osgDB::Registry::instance()->createLibraryNameForExtension(ext); + osgDB::Registry::instance()->loadLibrary(libName); + } + + std::string libName; + while (arguments.read("-l",libName)) + { + osgDB::Registry::instance()->loadLibrary(libName); + } + + while (arguments.read("-t",str)) + { + osg::Vec3 trans(0,0,0); + if( sscanf( str.c_str(), "%f,%f,%f", + &trans[0], &trans[1], &trans[2] ) != 3 ) + { + usage( argv[0], "Translation argument format incorrect." ); + return false; + } + oc.setTranslation( trans ); + do_convert = true; + } + + while (arguments.read("-o",str)) + { + osg::Vec3 from, to; + if( sscanf( str.c_str(), "%f,%f,%f-%f,%f,%f", + &from[0], &from[1], &from[2], + &to[0], &to[1], &to[2] ) + != 6 ) + { + float degrees; + osg::Vec3 axis; + // Try deg-axis format + if( sscanf( str.c_str(), "%f-%f,%f,%f", + °rees, &axis[0], &axis[1], &axis[2] ) != 4 ) + { + usage( argv[0], "Orientation argument format incorrect." ); + return false; + } + else + { + oc.setRotation( degrees, axis ); + do_convert = true; + } + } + else + { + oc.setRotation( from, to ); + do_convert = true; + } + + } + + while (arguments.read("--compressed")) + { + compressTextures = true; + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } + + for(int pos=1;possetOptions(options); - if( parse_args( argc, argv, fileNames, oc, options ) == false ) - return -1; - std::string fileNameOut("converted.osg"); if (fileNames.size()>1) { @@ -304,6 +357,16 @@ int main( int argc, char **argv ) if( do_convert ) root = oc.convert( root.get() ); + + if (compressTextures) + { + osg::notify(osg::NOTICE)<<"Need to implement compressed textures."<< std::endl; + + CompressTexturesVisitor ctv; + root->accept(ctv); + ctv.compress(); + + } if (osgDB::writeNodeFile(*root,fileNameOut)) {