From ab2fc1be762eb208a6f05c4d42ef760e12cf6117 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 7 Apr 2015 16:58:31 +0000 Subject: [PATCH] =?UTF-8?q?From=20Giampaolo=20Vigan=C3=B2,=20"you=20can=20?= =?UTF-8?q?find=20in=20the=20attached=20ZIP=20archive=20a=20fix=20for=203d?= =?UTF-8?q?s=20plugin=20transparent/diffuse=20textures=20and=20opacity=20m?= =?UTF-8?q?aps=20and=20the=20support=20for=20reflection=20map"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14825 16af8721-9629-0410-8352-f15c8da7e697 --- src/osgPlugins/3ds/ReaderWriter3DS.cpp | 115 +++++++++++++++++++++---- 1 file changed, 97 insertions(+), 18 deletions(-) diff --git a/src/osgPlugins/3ds/ReaderWriter3DS.cpp b/src/osgPlugins/3ds/ReaderWriter3DS.cpp index bb48dd256..0c25c3e69 100644 --- a/src/osgPlugins/3ds/ReaderWriter3DS.cpp +++ b/src/osgPlugins/3ds/ReaderWriter3DS.cpp @@ -1249,6 +1249,23 @@ ReaderWriter3DS::StateSetInfo ReaderWriter3DS::ReaderObject::createStateSet(Lib3 if (texture1_map) { if(textureTransparency) transparency = true; + + // a diffuse texture can be transparent (e.g. a PNG with alpha channel) + if (texture1_map->getImage()->isImageTranslucent()) transparency = true; + + // set UV scaling... + // to do: import offset and scaling + float uscale = mat->texture1_map.scale[0]; + float vscale = mat->texture1_map.scale[1]; + if (uscale != 1.0 || vscale != 1.0) + { + osg::ref_ptr texmat = new osg::TexMat(); + osg::Matrix uvScaling; + uvScaling.makeScale(osg::Vec3(uscale, vscale, 1.0)); + texmat->setMatrix(uvScaling); + stateset->setTextureAttributeAndModes(unit, texmat.get(), osg::StateAttribute::ON); + } + stateset->setTextureAttributeAndModes(unit, texture1_map, osg::StateAttribute::ON); double factor = mat->texture1_map.percent; @@ -1294,28 +1311,90 @@ ReaderWriter3DS::StateSetInfo ReaderWriter3DS::ReaderObject::createStateSet(Lib3 osg::Texture2D* opacity_map = createTexture(&(mat->opacity_map),"opacity_map", textureTransparency); if (opacity_map) { - if(opacity_map->getImage()->isImageTranslucent()) + // set UV scaling... + // to do: import offset and scaling + float uscale = mat->opacity_map.scale[0]; + float vscale = mat->opacity_map.scale[1]; + if (uscale != 1.0 || vscale != 1.0) { - transparency = true; - - stateset->setTextureAttributeAndModes(unit, opacity_map, osg::StateAttribute::ON); - - double factor = mat->opacity_map.percent; - - osg::TexEnvCombine* texenv = new osg::TexEnvCombine(); - texenv->setCombine_Alpha(osg::TexEnvCombine::INTERPOLATE); - texenv->setSource0_Alpha(osg::TexEnvCombine::TEXTURE); - texenv->setSource1_Alpha(osg::TexEnvCombine::PREVIOUS); - texenv->setSource2_Alpha(osg::TexEnvCombine::CONSTANT); - texenv->setConstantColor(osg::Vec4(factor, factor, factor, 1.0 - factor)); - stateset->setTextureAttributeAndModes(unit, texenv, osg::StateAttribute::ON); - - unit++; + osg::ref_ptr texmat = new osg::TexMat(); + osg::Matrix uvScaling; + uvScaling.makeScale(osg::Vec3(uscale, vscale, 1.0)); + texmat->setMatrix(uvScaling); + stateset->setTextureAttributeAndModes(unit, texmat.get(), osg::StateAttribute::ON); } - else + + double factor = mat->opacity_map.percent; + + // opacity map: add an alpha channel to the image to make opacity work + // (rebuid the image anyway if it must be rescaled according to factor) + if(!opacity_map->getImage()->isImageTranslucent() || factor<1.0) { - osg::notify(WARN)<<"The plugin does not support images without alpha channel for opacity"< osg_image = opacity_map->getImage(); + int nc = (int)osg_image->getPixelSizeInBits()/8; + unsigned char* orig_img_data = (unsigned char*)osg_image->getDataPointer(); + int n = osg_image->s()*osg_image->t()*4; + unsigned char* img_data = new unsigned char[n]; + // rebuild the texture with alpha channel (rescale according to map amount) + for (int i=0, j=0; isetImage(osg_image->s(),osg_image->t(),osg_image->r(), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, img_data, osg::Image::USE_NEW_DELETE); + opacity_map->setImage(osg_image.get()); } + + transparency = true; + + stateset->setTextureAttributeAndModes(unit, opacity_map, osg::StateAttribute::ON); + + // set up and enable the texture combiner + osg::TexEnvCombine* texenv = new osg::TexEnvCombine(); + + texenv->setCombine_RGB(osg::TexEnvCombine::REPLACE); + texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); + + texenv->setCombine_Alpha(osg::TexEnvCombine::MODULATE); + texenv->setSource0_Alpha(osg::TexEnvCombine::TEXTURE); + texenv->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA); + texenv->setSource1_Alpha(osg::TexEnvCombine::PRIMARY_COLOR); + texenv->setOperand1_Alpha(osg::TexEnvCombine::SRC_ALPHA); + + stateset->setTextureAttributeAndModes(unit, texenv, osg::StateAttribute::ON); + + osg::BlendFunc* blendfunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,osg::BlendFunc::ONE_MINUS_SRC_ALPHA); + stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON); + osg::TexEnv* tenv = new osg::TexEnv(); + tenv->setMode(osg::TexEnv::MODULATE); + stateset->setTextureAttributeAndModes(unit, tenv, osg::StateAttribute::ON); + + unit++; + } + + // derived from code in src/osgPlugins/fbx/fbxRMesh.cpp + osg::ref_ptr reflection_map = createTexture(&(mat->reflection_map),"reflection_map",textureTransparency); + if (reflection_map) + { + stateset->setTextureAttributeAndModes(unit, reflection_map, osg::StateAttribute::ON); + + // setup spherical map... + osg::ref_ptr texgen = new osg::TexGen(); + texgen->setMode(osg::TexGen::SPHERE_MAP); + stateset->setTextureAttributeAndModes(unit, texgen.get(), osg::StateAttribute::ON); + + // setup combiner for factor... + double factor = mat->reflection_map.percent; + osg::ref_ptr texenv = new osg::TexEnvCombine(); + texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); + texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); + texenv->setConstantColor(osg::Vec4(factor, factor, factor, factor)); + stateset->setTextureAttributeAndModes(unit, texenv.get(), osg::StateAttribute::ON); + unit++; } // material