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/

Reply via email to