Hi Roger,
I tested this code with a few models of the Collada test bank and not
all examples work like before. I did not take a look at the specific
code paths that these examples used.
Maybe it is wise that we set up a regression data set specifically
targeted at transparency.
--
Roland
________________________________
From: [email protected]
[mailto:[email protected]] On Behalf Of Roger
James
Sent: vrijdag 12 december 2008 17:04
To: OpenSceneGraph Users
Subject: Re: [osg-users] The Collada plugin and transparency
Ok,
Here is where I am at the moment with the handling of
transparency etc. Being a developer I have pasted in the actual code. I
must admit the handling of the FX_OPAQUE_RGB_XXX stuff does not make
much sense to me, but then I have never seen it used. Comments welcome.
void daeReader::processTransparencySettings(
domCommon_transparent_type *ctt, domCommon_float_or_param_type
*pTransparency, osg::StateSet *ss, osg::Material *material )
{
if (NULL == ctt && NULL == pTransparency)
return;
if (ctt && ctt->getTexture() != NULL)
{
osg::notify( osg::WARN ) << "Currently no support for
<texture> in <transparent> channel." << std::endl;
return;
}
// Fix up defaults acoording to 1.4.1 release notes
domFloat4 f4;
domFx_opaque_enum Opaque = FX_OPAQUE_ENUM_A_ONE;
if (NULL == ctt)
{
f4.append(0.0f);
f4.append(0.0f);
f4.append(0.0f);
f4.append(1.0f);
}
else
{
Opaque = ctt->getOpaque();
if (NULL != ctt->getColor())
{
f4 = ctt->getColor()->getValue();
}
else if ((NULL == ctt->getParam()) ||
!GetFloat4Param(ctt->getParam()->getRef(), f4))
{
f4.append(0.0f);
f4.append(0.0f);
f4.append(0.0f);
f4.append(1.0f);
}
}
domFloat Transparency;
if (NULL == pTransparency)
Transparency = 1.0f;
else
{
if (NULL != pTransparency->getFloat())
{
Transparency =
pTransparency->getFloat()->getValue();
if (m_AuthoringTool == GOOGLE_SKETCHUP) // Google
back to front support
Transparency = 1.0f - Transparency;
}
else if (NULL != pTransparency->getParam())
{
if
(GetFloatParam(pTransparency->getParam()->getRef(), Transparency))
{
if (m_AuthoringTool == GOOGLE_SKETCHUP) //
Google back to front support
Transparency = 1.0f - Transparency;
}
else
Transparency = 1.0f;
}
}
if (NULL != ctt || NULL != pTransparency)
{
// I assume that the presence of either a <tansparent>
or a <transparency> element
// means that the user may want some kind of alpha
blending
int SourceBlendFactor;
int DestBlendFactor;
bool HaveTranslucentDiffuseTexture = false;
bool SwitchOnTheBlender = false;
if ((NULL != ctt) &&
(GL_TRUE == ss->getTextureMode(0,
GL_TEXTURE_2D)) &&
(NULL !=
dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(0,
osg::StateAttribute::TEXTURE))) &&
(NULL !=
dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(0,
osg::StateAttribute::TEXTURE))->getImage()) &&
(dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(0,
osg::StateAttribute::TEXTURE))->getImage()->isImageTranslucent()))
HaveTranslucentDiffuseTexture = true;
osg::Vec4 Diffuse;
if (material)
Diffuse =
material->getDiffuse(osg::Material::FRONT_AND_BACK);
// Determine whether or not to switch on the blender and
which blending factors to use.
// I switch the blender on if the supplied (or default)
<transparent> and <transparency> elements work out as non opaque,
// or if they work out opaque and I have a translucent
diffuse texture or a non opaque value in the diffuse colour
switch(Opaque)
{
/*
case FX_OPAQUE_ENUM_RGB_ONE:
if ((Transparency * f4[0] > 0.99f) &&
(Transparency * f4[1] > 0.99f) &&
(Transparency * f4[2] > 0.99f) &&
(Transparency * f4[3] > 0.99f))
{
SourceBlendFactor = GL_SRC_COLOR;
DestBlendFactor = GL_ONE_MINUS_SRC_COLOR;
if (HaveTranslucentDiffuseTexture ||
((Diffuse.r() < 0.99f) && (Diffuse.g() < 0.99f) && (Diffuse.b() < 0.99f)
&& (Diffuse.a() < 0.99f)))
SwitchOnTheBlender = true;
}
else
{
SourceBlendFactor = GL_CONSTANT_COLOR;
DestBlendFactor =
GL_ONE_MINUS_CONSTANT_COLOR;
SwitchOnTheBlender = true;
}
break;
case FX_OPAQUE_ALPHA_ZERO:
if (Transparency * f4[3] < 0.01f)
{
SourceBlendFactor = GL_ONE_MINUS_SRC_ALPHA;
DestBlendFactor = GL_SRC_ALPHA;
if (HaveTranslucentDiffuseTexture ||
(Diffuse.a() > 0.01f))
SwitchOnTheBlender = true;
}
else
{
SourceBlendFactor =
GL_ONE_MINUS_CONSTANT_ALPHA;
DestBlendFactor = GL_CONSTANT_ALPHA;
SwitchOnTheBlender = true;
}
break;
*/
case FX_OPAQUE_ENUM_RGB_ZERO:
if ((Transparency * f4[0] < 0.01f) &&
(Transparency * f4[1] < 0.01f) &&
(Transparency * f4[2] < 0.01f) &&
(Transparency * f4[3] < 0.01f))
{
SourceBlendFactor = GL_ONE_MINUS_SRC_COLOR;
DestBlendFactor = GL_SRC_COLOR;
if (HaveTranslucentDiffuseTexture ||
((Diffuse.r() > 0.01f) && (Diffuse.g() > 0.01f) && (Diffuse.b() > 0.01f)
&& (Diffuse.a() > 0.01f)))
SwitchOnTheBlender = true;
}
else
{
SourceBlendFactor =
GL_ONE_MINUS_CONSTANT_COLOR;
DestBlendFactor = GL_CONSTANT_COLOR;
SwitchOnTheBlender = true;
}
break;
default:
if (Transparency * f4[3] > 0.99f)
{
SourceBlendFactor = GL_SRC_ALPHA;
DestBlendFactor = GL_ONE_MINUS_SRC_ALPHA;
if (HaveTranslucentDiffuseTexture ||
(Diffuse.a() < 0.99f))
SwitchOnTheBlender = true;
}
else
{
SourceBlendFactor = GL_CONSTANT_ALPHA;
DestBlendFactor =
GL_ONE_MINUS_CONSTANT_ALPHA;
SwitchOnTheBlender = true;
}
break;
}
if ((SourceBlendFactor == GL_CONSTANT_COLOR) ||
(SourceBlendFactor == GL_ONE_MINUS_CONSTANT_COLOR)
||
(SourceBlendFactor == GL_CONSTANT_ALPHA) ||
(SourceBlendFactor == GL_ONE_MINUS_CONSTANT_ALPHA))
{
osg::BlendColor *bc = new osg::BlendColor();
bc->setConstantColor(osg::Vec4( f4[0] *
Transparency, f4[1] * Transparency, f4[2] * Transparency, f4[3] *
Transparency ));
ss->setAttribute( bc );
}
osg::BlendFunc *bf = new
osg::BlendFunc(SourceBlendFactor, DestBlendFactor);
ss->setAttribute( bf );
ss->setMode( GL_BLEND, GL_TRUE );
ss->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
ss->setRenderBinDetails( 10, "DepthSortedBin" );
}
}
Roger
This e-mail and its contents are subject to the DISCLAIMER at
http://www.tno.nl/disclaimer/email.html
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org