|
|
|
@ -460,6 +460,46 @@ namespace
|
|
|
|
|
|
|
|
|
|
namespace MWRender
|
|
|
|
|
{
|
|
|
|
|
class TransparencyUpdater : public SceneUtil::StateSetUpdater
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
TransparencyUpdater(const float alpha)
|
|
|
|
|
: mAlpha(alpha)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setAlpha(const float alpha)
|
|
|
|
|
{
|
|
|
|
|
mAlpha = alpha;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
virtual void setDefaults(osg::StateSet* stateset)
|
|
|
|
|
{
|
|
|
|
|
osg::Material* material = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
|
|
|
|
|
|
|
|
|
|
osg::BlendFunc* blendfunc (new osg::BlendFunc);
|
|
|
|
|
stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
|
|
|
|
|
|
|
|
|
// FIXME: overriding diffuse/ambient/emissive colors
|
|
|
|
|
material = new osg::Material;
|
|
|
|
|
material->setColorMode(osg::Material::OFF);
|
|
|
|
|
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,mAlpha));
|
|
|
|
|
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
|
|
|
|
|
stateset->setAttributeAndModes(material, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
|
|
|
|
stateset->addUniform(new osg::Uniform("colorMode", 0), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/)
|
|
|
|
|
{
|
|
|
|
|
osg::Material* material = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
|
|
|
|
|
material->setAlpha(osg::Material::FRONT_AND_BACK, mAlpha);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
float mAlpha;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class GlowUpdater : public SceneUtil::StateSetUpdater
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
@ -1772,32 +1812,21 @@ namespace MWRender
|
|
|
|
|
return;
|
|
|
|
|
mAlpha = alpha;
|
|
|
|
|
|
|
|
|
|
// TODO: we use it to fade actors away too, but it would be nice to have a dithering shader instead.
|
|
|
|
|
if (alpha != 1.f)
|
|
|
|
|
{
|
|
|
|
|
// If we have an existing material for alpha transparency, just override alpha level
|
|
|
|
|
osg::StateSet* stateset = mObjectRoot->getOrCreateStateSet();
|
|
|
|
|
osg::Material* material = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
|
|
|
|
|
if (material)
|
|
|
|
|
if (mTransparencyUpdater == nullptr)
|
|
|
|
|
{
|
|
|
|
|
material->setAlpha(osg::Material::FRONT_AND_BACK, alpha);
|
|
|
|
|
mTransparencyUpdater = new TransparencyUpdater(alpha);
|
|
|
|
|
mObjectRoot->addUpdateCallback(mTransparencyUpdater);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
osg::BlendFunc* blendfunc (new osg::BlendFunc);
|
|
|
|
|
stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
|
|
|
|
|
|
|
|
|
// FIXME: overriding diffuse/ambient/emissive colors
|
|
|
|
|
material = new osg::Material;
|
|
|
|
|
material->setColorMode(osg::Material::OFF);
|
|
|
|
|
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,alpha));
|
|
|
|
|
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
|
|
|
|
|
stateset->setAttributeAndModes(material, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
|
|
|
|
stateset->addUniform(new osg::Uniform("colorMode", 0), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
|
|
|
|
mObjectRoot->setStateSet(stateset);
|
|
|
|
|
}
|
|
|
|
|
mTransparencyUpdater->setAlpha(alpha);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mObjectRoot->removeUpdateCallback(mTransparencyUpdater);
|
|
|
|
|
mTransparencyUpdater = nullptr;
|
|
|
|
|
mObjectRoot->setStateSet(nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|