From 8995824aa4e2a5b1d24268a039bf9775a417e206 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 9 Mar 2011 15:55:35 +0000 Subject: [PATCH] From Jan Peciva, "please, find attached updates to Inventor plugin: - improved transparency - do not treat 32-bit textures as transparent textures unless they really contain transparent pixels - error messages forwarded to osg::notify" --- .../Inventor/ConvertFromInventor.cpp | 31 ++++++++++---- src/osgPlugins/Inventor/ReaderWriterIV.cpp | 41 ++++++++++++++++++- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/osgPlugins/Inventor/ConvertFromInventor.cpp b/src/osgPlugins/Inventor/ConvertFromInventor.cpp index 765540197..fef8683d8 100644 --- a/src/osgPlugins/Inventor/ConvertFromInventor.cpp +++ b/src/osgPlugins/Inventor/ConvertFromInventor.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -1697,28 +1698,44 @@ ConvertFromInventor::getStateSet(SoCallbackAction* action) // Set transparency SbBool hasTextureTransparency = FALSE; if (ivTexture) { - SbVec2s tmp; + SbVec2s size(0, 0); int bpp = 0; + const unsigned char *data = NULL; if (ivTexture->isOfType(SoTexture2::getClassTypeId())) - ((SoTexture2*)ivTexture)->image.getValue(tmp, bpp); + data = ((SoTexture2*)ivTexture)->image.getValue(size, bpp); #ifdef __COIN__ else if (ivTexture->isOfType(SoVRMLImageTexture::getClassTypeId())) { const SbImage *img = ((SoVRMLImageTexture*)ivTexture)->getImage(); - if (img) img->getValue(tmp, bpp); + if (img) + data = img->getValue(size, bpp); } #endif - hasTextureTransparency = bpp==4 || bpp==2; + + // look whether texture really contains transparency + if ((bpp==4 || bpp==2) && data) { + data += bpp - 1; + for (int y=0; y 0 || hasTextureTransparency) { - osg::ref_ptr transparency = new osg::BlendFunc; - stateSet->setAttributeAndModes(transparency.get(), - osg::StateAttribute::ON); + // Blending to SRC_APLHA and ONE_MINUS_SRC_ALPHA + stateSet->setAttributeAndModes(new osg::BlendFunc); + + // Disable depth writes + stateSet->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL, 0., 1., false)); // Enable depth sorting for transparent objects stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + stateSet->setNestRenderBins(false); } // Set linewidth diff --git a/src/osgPlugins/Inventor/ReaderWriterIV.cpp b/src/osgPlugins/Inventor/ReaderWriterIV.cpp index c3a819d8a..d21667e00 100644 --- a/src/osgPlugins/Inventor/ReaderWriterIV.cpp +++ b/src/osgPlugins/Inventor/ReaderWriterIV.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -21,6 +24,7 @@ // forward declarations of static functions static void addSearchPaths(const osgDB::FilePathList *searchPaths); static void removeSearchPaths(const osgDB::FilePathList *searchPaths); +static void errorCallback(const SoError *error, void * data); // Register with Registry to instantiate the inventor reader. @@ -52,16 +56,51 @@ void ReaderWriterIV::initInventor() const SoNodeKit::init(); SoInteraction::init(); + // Redirect error messages to OSG notify + SoError::setHandlerCallback(errorCallback, NULL); + SoDebugError::setHandlerCallback(errorCallback, NULL); + SoMemoryError::setHandlerCallback(errorCallback, NULL); + SoReadError::setHandlerCallback(errorCallback, NULL); + #ifdef __COIN__ // Disable delayed loading of VRML textures SoVRMLImageTexture::setDelayFetchURL(FALSE); - + // initialize convertor ConvertFromInventor::init(); #endif } +static void errorCallback(const SoError *error, void *data) +{ + // note: Coin and SGI Inventor puts "Inventor read error..." or "Coin warning..." + // introduction string to the error message, so we do not prepend the error message + // by anything. + + if (error->isOfType(SoDebugError::getClassTypeId())) + { + switch (((SoDebugError*)error)->getSeverity()) + { + case SoDebugError::INFO: + OSG_INFO << error->getDebugString().getString() << std::endl; + break; + case SoDebugError::WARNING: + OSG_WARN << error->getDebugString().getString() << std::endl; + break; + case SoDebugError::ERROR: + default: + OSG_WARN << error->getDebugString().getString() << std::endl; + break; + } + } + else + { + OSG_WARN << error->getDebugString().getString() << std::endl; + } +} + + /** * Read from SoInput and convert to OSG. * This is a method used by readNode(string,options) and readNode(istream,options).