virtual bool isTransparent(osg::StateSet& stateset) { bool hasTranslucentTexture = false; bool hasBlendFunc = dynamic_cast<osg::BlendFunc*>(stateset.getAttribute(osg::StateAttribute::BLENDFUNC))!=0; bool hasTransparentRenderingHint = stateset.getRenderingHint()==osg::StateSet::TRANSPARENT_BIN; bool hasDepthSortBin = (stateset.getRenderBinMode()==osg::StateSet::USE_RENDERBIN_DETAILS)?(stateset.getBinName()=="DepthSortedBin"):false; bool hasTexture = false; // search for the existence of any texture object attributes for(unsigned int i=0;i<stateset.getTextureAttributeList().size();++i) { osg::Texture* texture = dynamic_cast<osg::Texture*>(stateset.getTextureAttribute(i,osg::StateAttribute::TEXTURE)); if (texture) { hasTexture = true; for (unsigned int im=0;im<texture->getNumImages();++im) { osg::Image* image = texture->getImage(im); if (image && image->isImageTranslucent()) hasTranslucentTexture = true; } } } if (hasTranslucentTexture || hasBlendFunc || hasTransparentRenderingHint || hasDepthSortBin) { ++_numTransparent; bool makeNonTransparent = false; switch(_mode) { case(MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE): if (hasTexture && !hasTranslucentTexture) { makeNonTransparent = true; } break; case(MAKE_ALL_STATESET_OPAQUE): makeNonTransparent = true; break; default: makeNonTransparent = false; break; } if (makeNonTransparent) { stateset.removeAttribute(osg::StateAttribute::BLENDFUNC); stateset.removeMode(GL_BLEND); stateset.setRenderingHint(osg::StateSet::DEFAULT_BIN); ++_numTransparentMadeOpaque; } return true; } else { ++_numOpaque; return false; } }