Hi Marcus,
The test file I included was from the latest version of Feeling
Softwares 3dsmax exporter. Is there any reason they would move from the
old mode to this mode, is this a Playstation thing ?
It's not a special case, but it is a case. ;) The <transparent> opaque
attribute has two values in 1.4.1 (and will have 4 values in 1.4.2 next
year most likely) that are: A_ONE and RGB_ZERO.
The default is A_ONE and that is more compatible with OpenGL (and RGBA
colors and texture usages). The OSG plug-in is hardcoded to handle the
A_ONE default case. This test file is using RGB_ZERO for whatever
reason.
I'm attempting to update daeRMaterial to handle both cases at the
moment, but it's not clear to me how to handle the RGB_ZERO mode.
I notice there is a daeReader::processTransparentType()
method that is going some way towards this.
Yes I see that function is only partly processing the <transparent>
element. It needs to handle the opaque attribute to do the right job.
There also needs to be another function to process the <transparency>
element, as those two elements work in combination.
Regards,
Marcus
This is where I'm heading, but the RGB_ZERO case is just showing black
at the moment.
osg::StateAttribute
*daeReader::processTransparentType(domCommon_transparent_type *ctt,
domCommon_float_or_param_type *ctc,
osg::StateSet *ss )
{
osg::Vec4 transparent(0,0,0,1);
float transparency=1.0;
if ( ctt == NULL && ctc == NULL)
{
return 0;
}
if (ctt && !ctc)
{
domFloat4 &f4 = ctt->getColor()->getValue();
transparent.set(f4[0], f4[1], f4[2], f4[3]);
}
else if (ctc && !ctt)
{
transparency = ctc->getFloat()->getValue();
}
else
{
domFloat4 &f4 = ctt->getColor()->getValue();
transparent.set(f4[0], f4[1], f4[2], f4[3]);
transparency = ctc->getFloat()->getValue();
}
osg::notify( osg::WARN ) << "transparent " << transparent[0]<< " "
<< transparent[1]<< " "
<< transparent[2]<< " "
<< transparent[3]<< " "
<< std::endl;
osg::StateAttribute *sa = NULL;
if (!ctt->getOpaque())
{
// todo ...
}
else
{
switch(ctt->getOpaque())
{
case FX_OPAQUE_ENUM_A_ONE:
osg::notify( osg::WARN ) << "<transparent> opaque mode
A_ONE" << std::endl;
if ( ctt->getColor() != NULL )
{
osg::Vec4 tcol(transparent);
tcol *= transparency;
//##compliant with OSG 1.0 API
osg::BlendColor *bc = new osg::BlendColor();
bc->setConstantColor(tcol);
ss->setAttribute( bc );
ss->setMode( GL_BLEND, GL_TRUE );
ss->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
ss->setRenderBinDetails( 10, "DepthSortedBin" );
}
else if ( ctt->getTexture() != NULL )
{
sa = processTexture( ctt->getTexture() );
osg::BlendFunc *bf = new osg::BlendFunc( GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA );
ss->setAttribute( bf );
ss->setMode( GL_BLEND, GL_TRUE );
ss->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
ss->setRenderBinDetails( 10, "DepthSortedBin" );
}
break;
case FX_OPAQUE_ENUM_RGB_ZERO:
osg::notify( osg::WARN ) << "<transparent> opaque mode
RGB_ZERO." << std::endl;
if ( ctt->getColor() != NULL )
{
float luminance = (transparent[0] * 0.212671) +
(transparent[1] * 0.715160) +
(transparent[2] * 0.072169);
osg::Vec4
tcol(transparent[0],transparent[1],transparent[2],luminance);
tcol *= transparency;
osg::notify( osg::WARN ) << "tcol " << tcol[0]<< " "
<< tcol[1]<< " "
<< tcol[2]<< " "
<< tcol[3]<< " "
<< std::endl;
osg::BlendColor *bc = new osg::BlendColor();
ss->setAttribute( bc );
osg::BlendFunc *bf = new osg::BlendFunc(
GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR );
bc->setConstantColor(tcol);
ss->setAttribute( bf );
ss->setMode( GL_BLEND, GL_TRUE );
ss->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
ss->setRenderBinDetails( 10, "DepthSortedBin" );
}
else if ( ctt->getTexture() != NULL )
{
// todo: adapt as above ...
sa = processTexture( ctt->getTexture() );
osg::BlendFunc *bf = new osg::BlendFunc( GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA );
ss->setAttribute( bf );
ss->setMode( GL_BLEND, GL_TRUE );
ss->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
ss->setRenderBinDetails( 10, "DepthSortedBin" );
}
break;
default:
osg::notify( osg::WARN ) << "Unhandled <transparent> opaque
mode." << std::endl;
return NULL;
break;
}
}
return sa;
}
You posted
In RGB_ZERO opaque mode you compute per component transparency blending:
result.r = fb.r * (transparent.r * transparency) + mat.r *
(1.0f - transparent.r * transparency)
result.g = fb.g * (transparent.g * transparency) + mat.g *
(1.0f - transparent.g * transparency)
result.b = fb.b * (transparent.b * transparency) + mat.b *
(1.0f - transparent.b * transparency)
Plugging in the mat values for the diffuse component we get:
result.rgb = [ 0.988235 0.909804 0.019608 ]
... the material color replaces the framebuffer (fb) color opaquely.
But result.a = 0.0. Is that meaningful. Are the fb colors pre-multiplied
by alpha, opengl experts ?
-Drew
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/