From 392232ec06e48ff54194f8282b25c12e66c240af Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 3 Oct 2006 09:55:28 +0000 Subject: [PATCH] From Brede Johansen, "This submission adds multitexture support for detecting translucent images used to enable alpha blending. Mesh was syncronized with featureset from Face record." --- src/osgPlugins/OpenFlight/GeometryRecords.cpp | 168 ++++++++++++------ 1 file changed, 110 insertions(+), 58 deletions(-) diff --git a/src/osgPlugins/OpenFlight/GeometryRecords.cpp b/src/osgPlugins/OpenFlight/GeometryRecords.cpp index 802ad8463..ec6a82665 100644 --- a/src/osgPlugins/OpenFlight/GeometryRecords.cpp +++ b/src/osgPlugins/OpenFlight/GeometryRecords.cpp @@ -46,7 +46,12 @@ class Face : public PrimaryRecord public: Face() : - _primaryColor(1,1,1,1) + _primaryColor(1,1,1,1), + _drawFlag(SOLID_NO_BACKFACE), + _template(FIXED_NO_ALPHA_BLENDING), + _transparency(0), + _flags(0), + _lightMode(FACE_COLOR) { } @@ -208,7 +213,7 @@ protected: std::string id = in.readString(8); /*int32 IRColor =*/ in.readInt32(); /*int16 relativePriority =*/ in.readInt16(); - _drawFlag = in.readUInt8(); + _drawFlag = in.readUInt8(SOLID_NO_BACKFACE); uint8 texturedWhite = in.readUInt8(); int16 primaryNameIndex = in.readInt16(-1); /*int16 secondaryNameIndex =*/ in.readInt16(-1); @@ -298,14 +303,12 @@ protected: stateset->setMode(GL_LIGHTING, isLit() ? osg::StateAttribute::ON : osg::StateAttribute::OFF); // Material - bool isTransparentMaterial = false; if (isLit()) { osg::Vec4 col = _primaryColor; col.a() = 1.0f - getTransparency(); osg::Material* material = document.getOrCreateMaterialPool()->getOrCreateMaterial(materialIndex,col); stateset->setAttribute(material); - isTransparentMaterial = material->getDiffuse(osg::Material::FRONT).a() < 0.99f; } // Shaders @@ -326,30 +329,6 @@ protected: stateset->merge(*textureStateSet); } - // Translucent image? - bool isImageTranslucent = false; - if (textureStateSet) - { - if (document.getUseTextureAlphaForTransparancyBinning()) - { - osg::Texture2D* texture = dynamic_cast(textureStateSet->getTextureAttribute(0,osg::StateAttribute::TEXTURE)); - if (texture) - { - osg::Image* image = texture->getImage(); - if (image && image->isImageTranslucent()) - isImageTranslucent = true; - } - } - } - - // Enable alpha blend? - if (isAlphaBlend() || isTransparent() || isTransparentMaterial || isImageTranslucent) - { - static osg::ref_ptr blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA); - stateset->setAttributeAndModes(blendFunc.get(), osg::StateAttribute::ON); - stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - } - // Cull face switch(_drawFlag) { @@ -466,6 +445,41 @@ protected: } } + osg::StateSet* stateset = _geode->getOrCreateStateSet(); + + // Translucent image? + bool isImageTranslucent = false; + if (document.getUseTextureAlphaForTransparancyBinning()) + { + for (unsigned int i=0; igetTextureAttributeList().size(); ++i) + { + osg::StateAttribute* sa = stateset->getTextureAttribute(i,osg::StateAttribute::TEXTURE); + osg::Texture2D* texture = dynamic_cast(sa); + if (texture) + { + osg::Image* image = texture->getImage(); + if (image && image->isImageTranslucent()) + isImageTranslucent = true; + } + } + } + + // Transparent Material? + bool isMaterialTransparent = false; + osg::Material* material = dynamic_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); + if (material) + { + isMaterialTransparent = material->getDiffuse(osg::Material::FRONT).a() < 0.99f; + } + + // Enable alpha blend? + if (isAlphaBlend() || isTransparent() || isImageTranslucent || isMaterialTransparent) + { + static osg::ref_ptr blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA); + stateset->setAttributeAndModes(blendFunc.get(), osg::StateAttribute::ON); + stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + } + if (document.getUseBillboardCenter()) { // Set billboard rotation point to center of face. @@ -659,12 +673,16 @@ class Mesh : public PrimaryRecord uint8 _lightMode; osg::ref_ptr _geode; - osg::ref_ptr _geometry; public: Mesh() : - _primaryColor(1,1,1,1) + _primaryColor(1,1,1,1), + _drawFlag(SOLID_NO_BACKFACE), + _template(FIXED_NO_ALPHA_BLENDING), + _transparency(0), + _flags(0), + _lightMode(FACE_COLOR) { } @@ -754,7 +772,7 @@ protected: in.forward(4); /*int32 IRColor =*/ in.readInt32(); /*int16 relativePriority =*/ in.readInt16(); - _drawFlag = in.readUInt8(); + _drawFlag = in.readUInt8(SOLID_NO_BACKFACE); uint8 texturedWhite = in.readUInt8(); int16 primaryNameIndex = in.readInt16(-1); /*int16 secondaryNameIndex =*/ in.readInt16(-1); @@ -840,14 +858,12 @@ protected: stateset->setMode(GL_LIGHTING, isLit() ? osg::StateAttribute::ON : osg::StateAttribute::OFF); // Material - bool isTransparentMaterial = false; if (isLit()) { osg::Vec4 col = _primaryColor; col.a() = 1.0f - getTransparency(); osg::Material* material = document.getOrCreateMaterialPool()->getOrCreateMaterial(materialIndex,col); stateset->setAttribute(material); - isTransparentMaterial = material->getDiffuse(osg::Material::FRONT).a() < 0.99f; } // Shaders @@ -868,30 +884,6 @@ protected: stateset->merge(*textureStateSet); } - // Translucent image? - bool isImageTranslucent = false; - if (textureStateSet) - { - if (document.getUseTextureAlphaForTransparancyBinning()) - { - osg::Texture2D* texture = dynamic_cast(textureStateSet->getTextureAttribute(0,osg::StateAttribute::TEXTURE)); - if (texture) - { - osg::Image* image = texture->getImage(); - if (image && image->isImageTranslucent()) - isImageTranslucent = true; - } - } - } - - // Enable alpha blend? - if (isAlphaBlend() || isTransparent() || isTransparentMaterial || isImageTranslucent) - { - static osg::ref_ptr blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA); - stateset->setAttributeAndModes(blendFunc.get(), osg::StateAttribute::ON); - stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - } - // Cull face switch(_drawFlag) { @@ -932,7 +924,67 @@ protected: _parent->addChild(*_geode); } - virtual ~Mesh() {} + virtual void popLevel(Document& document) + { + if (_geode.valid()) + { + osg::StateSet* stateset = _geode->getOrCreateStateSet(); + + // Translucent image? + bool isImageTranslucent = false; + if (document.getUseTextureAlphaForTransparancyBinning()) + { + for (unsigned int i=0; igetTextureAttributeList().size(); ++i) + { + osg::StateAttribute* sa = stateset->getTextureAttribute(i,osg::StateAttribute::TEXTURE); + osg::Texture2D* texture = dynamic_cast(sa); + if (texture) + { + osg::Image* image = texture->getImage(); + if (image && image->isImageTranslucent()) + isImageTranslucent = true; + } + } + } + + // Transparent Material? + bool isMaterialTransparent = false; + osg::Material* material = dynamic_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); + if (material) + { + isMaterialTransparent = material->getDiffuse(osg::Material::FRONT).a() < 0.99f; + } + + // Enable alpha blend? + if (isAlphaBlend() || isTransparent() || isImageTranslucent || isMaterialTransparent) + { + static osg::ref_ptr blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA); + stateset->setAttributeAndModes(blendFunc.get(), osg::StateAttribute::ON); + stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + } + + if (document.getUseBillboardCenter()) + { + // Set billboard rotation point to center of face. + osg::Billboard* billboard = dynamic_cast(_geode.get()); + if (billboard) + { + for (unsigned int i=0; igetNumDrawables(); ++i) + { + osg::BoundingBox bb = billboard->getDrawable(i)->getBound(); + billboard->setPosition(i,bb.center()); + + osgUtil::TransformAttributeFunctor tf(osg::Matrix::translate(-bb.center())); + billboard->getDrawable(i)->accept(tf); + + billboard->getDrawable(i)->dirtyBound(); + } + + billboard->dirtyBound(); + } + } + } + } }; RegisterRecordProxy g_Mesh(MESH_OP);