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
