设置物体透明,trans是透明度的设置,这里如果没有setRenderingHint()虽然看起来是透明的,但模型还是会遮挡其他模型。然后就是BLEND要打开,光照和深度测试要关掉。模型的材质也要事先设置。并将材质保存起来以便恢复的时候调用。
osg::Material *material = new osg::Material;
material->setDiffuse(osg::Material::FRONT, osg::Vec4(0.4, 0.4, 0.4, 1.0));
material->setAmbient(osg::Material::FRONT, osg::Vec4(0.4, 0.4, 0.4, 1.0));
material->setShininess(osg::Material::FRONT, 90.0);
scene->getOrCreateStateSet()->setAttribute(material);
originmaterial = material;
下面是设置透明的代码
void setTransparent(osg::Node *node,float trans)
{
osg::StateSet * stateset = node->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setMode(GL_DEPTH, osg::StateAttribute::OFF);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
osg::BlendColor *bc = new osg::BlendColor(osg::Vec4(1.0, 1.0, 1.0, 1.0));
osg::ref_ptr<osg::BlendFunc>blendFunc = new osg::BlendFunc();
blendFunc->setSource(osg::BlendFunc::CONSTANT_ALPHA);
blendFunc->setDestination(osg::BlendFunc::ONE_MINUS_CONSTANT_ALPHA);
stateset->setAttributeAndModes(bc, osg::StateAttribute::ON);
stateset->setAttributeAndModes(blendFunc, osg::StateAttribute::ON);
bc->setConstantColor(osg::Vec4(1, 1, 1, trans));//第四个参数可用调节透明度
}
再把模型变回来。
一开始遇到了问题,虽然模型也恢复了正常的状态,但console还是提示warning。
warning:detected OpenGL error ‘invalid enumerant’ at after renderbin::draw()
最后排查原因是,stateset->setMode(GL_DEPTH, osg::StateAttribute::ON);这一句导致的。大概默认就是开启了深度测试,如果再设置它打开,就会出问题吧。。不知道为什么。
恢复模型成正常状态就是获取到模型的stateset,然后再重新打开光照,关掉混合,再附上之前保存的材质。
osg::StateSet * stateset = picked->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON );
stateset->setMode(GL_BLEND, osg::StateAttribute::OFF);
stateset->setAttribute(originmaterial);