Hi Neil,

Could you send me the whole modified file as I'm afraid the mail
client just blitz's code copy and pasted into emails making it
impossible to do a reliable merge.

Thanks,
Robert.

On Mon, Mar 2, 2009 at 12:38 PM,  <[email protected]> wrote:
> Hi Robert,
>
> I've spent the past four days playing with PNG files on 3DS objects, and I 
> think I may have come across a small issue with the 3DS loader.
>
> At the company where I work we model literally thousands of 3DS models for 
> all types of objects. Most don't have transparent textures applied to them, 
> but a few do. The issue is that a texture may have an alpha channel defined, 
> yet its 3DS material definition is not marked as being an alpha source, or 
> transparent. This can happen for any number of modelling reasons (so I'm 
> told) but the net effect is that when a 3DS object is loaded with such a 
> material applied, the stateset creation for the 3DS geometry omits to add the 
> GL_BLEND attribute as neither of the conditions that it currently tests for 
> are satisfied under this scenario.
>
> However, one thing that is apparently an indication of transparency/alpha 
> information that we do make use of when modelling, but that the 3DS reader 
> omits to test, is that we assign to the transparent texture to the 
> opacity_map of the 3DS material structure.
>
> Now, having discussed with our modellers the theory behind the opacity map, 
> it seems that it is safe to say that if an opacity map is specified, then the 
> reader should really apply the GL_BLEND attribute as it is an indication of 
> some form of blending being required between materials.
>
> With this in mind, I have made a minor change to the function createStateSet 
> below, from the ReaderWriter3DS.cpp file, that checks for an opacity map 
> having been specified, and in such a scenario the GL_BLEND attribute is 
> applied to the geometry. This fixed our issue, and thought it might be 
> helpful to others.
>
> Kind regards
>
> Neil Hughes.
>
> osg::StateSet* ReaderWriter3DS::ReaderObject::createStateSet(Lib3dsMaterial 
> *mat, const osgDB::ReaderWriter::Options* options)
> {
>    if (mat==NULL) return NULL;
>
>    osg::StateSet* stateset = new osg::StateSet;
>
>    osg::Material* material = new osg::Material;
>
>    float transparency = mat->transparency;
>    float alpha = 1.0f-transparency;
>
>    osg::Vec4 ambient(mat->ambient[0],mat->ambient[1],mat->ambient[2],alpha);
>    osg::Vec4 diffuse(mat->diffuse[0],mat->diffuse[1],mat->diffuse[2],alpha);
>    osg::Vec4 
> specular(mat->specular[0],mat->specular[1],mat->specular[2],alpha);
>    specular *= mat->shin_strength;
>
>    float shininess = mat->shininess;
>        material->setName(mat->name);
>    material->setAmbient(osg::Material::FRONT_AND_BACK,ambient);
>    material->setDiffuse(osg::Material::FRONT_AND_BACK,diffuse);
>    material->setSpecular(osg::Material::FRONT_AND_BACK,specular);
>    material->setShininess(osg::Material::FRONT_AND_BACK,shininess*128.0f);
>
>    stateset->setAttribute(material);
>
>    bool textureTransparancy=false;
>    osg::Texture2D* texture1_map = 
> createTexture(&(mat->texture1_map),"texture1_map",textureTransparancy, 
> options);
>    if (texture1_map)
>    {
>        
> stateset->setTextureAttributeAndModes(0,texture1_map,osg::StateAttribute::ON);
>
>        if (!textureTransparancy)
>        {
>            // from an email from Eric Hamil, September 30, 2003.
>            // According to the 3DS spec, and other
>            // software (like Max, Lightwave, and Deep Exploration) a 3DS 
> material that has
>            // a non-white diffuse base color and a 100% opaque bitmap 
> texture, will show the
>            // texture with no influence from the base color.
>
>            // so we'll override material back to white.
>            // and no longer require the decal hack below...
> #if 0
>            // Eric orignal fallback
>            osg::Vec4 white(1.0f,1.0f,1.0f,alpha);
>            material->setAmbient(osg::Material::FRONT_AND_BACK,white);
>            material->setDiffuse(osg::Material::FRONT_AND_BACK,white);
>            material->setSpecular(osg::Material::FRONT_AND_BACK,white);
> #else
>            // try alternative to avoid staturating with white
>            // setting white as per OpenGL defaults.
>            
> material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(0.2f,0.2f,0.2f,alpha));
>            
> material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(0.8f,0.8f,0.8f,alpha));
>            
> material->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,alpha));
> #endif
>        }
>
> // no longer required...
> //         bool decal = false;
> //
> //         // not sure exactly how to interpret what is best for .3ds
> //         // but the default text env MODULATE doesn't work well, and
> //         // DECAL seems to work better.
> //         osg::TexEnv* texenv = new osg::TexEnv;
> //         if (decal)
> //         {
> //             texenv->setMode(osg::TexEnv::DECAL);
> //         }
> //         else
> //         {
> //             texenv->setMode(osg::TexEnv::MODULATE);
> //         }
> //        stateset->setTextureAttribute(0,texenv);
>    }
>
>        //if (transparency>0.0f || textureTransparancy)
>    if (transparency>0.0f || textureTransparancy || mat->opacity_map.flags!=0)
>    {
>        stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
>        stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
>    }
>
> /*
>    osg::ref_ptr<osg::Texture> texture1_mask = 
> createTexture(&(mat->texture1_mask),"texture1_mask",textureTransparancy);
>    osg::ref_ptr<osg::Texture> texture2_map = 
> createTexture(&(mat->texture2_map),"texture2_map",textureTransparancy);
>    osg::ref_ptr<osg::Texture> texture2_mask = 
> createTexture(&(mat->texture2_mask),"texture2_mask",textureTransparancy);
>    osg::ref_ptr<osg::Texture> opacity_map = 
> createTexture(&(mat->opacity_map),"opacity_map",textureTransparancy);
>    osg::ref_ptr<osg::Texture> opacity_mask = 
> createTexture(&(mat->opacity_mask),"opacity_mask",textureTransparancy);
>    osg::ref_ptr<osg::Texture> bump_map = 
> createTexture(&(mat->bump_map),"bump_map",textureTransparancy);
>    osg::ref_ptr<osg::Texture> bump_mask = 
> createTexture(&(mat->bump_mask),"bump_mask",textureTransparancy);
>    osg::ref_ptr<osg::Texture> specular_map = 
> createTexture(&(mat->specular_map),"specular_map",textureTransparancy);
>    osg::ref_ptr<osg::Texture> specular_mask = 
> createTexture(&(mat->specular_mask),"specular_mask",textureTransparancy);
>    osg::ref_ptr<osg::Texture> shininess_map = 
> createTexture(&(mat->shininess_map),"shininess_map",textureTransparancy);
>    osg::ref_ptr<osg::Texture> shininess_mask = 
> createTexture(&(mat->shininess_mask),"shininess_mask",textureTransparancy);
>    osg::ref_ptr<osg::Texture> self_illum_map = 
> createTexture(&(mat->self_illum_map),"self_illum_map",textureTransparancy);
>    osg::ref_ptr<osg::Texture> self_illum_mask = 
> createTexture(&(mat->self_illum_mask),"self_illum_mask",textureTransparancy);
>    osg::ref_ptr<osg::Texture> reflection_map = 
> createTexture(&(mat->reflection_map),"reflection_map",textureTransparancy);
>    osg::ref_ptr<osg::Texture> reflection_mask = 
> createTexture(&(mat->reflection_mask),"reflection_mask",textureTransparancy);
> */
>    return stateset;
> }
>
>
>
>
>
>
>
>
>
>
> _______________________________________________
> osg-submissions mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to