diff --git a/src/osgPlugins/ac/ac3d.cpp b/src/osgPlugins/ac/ac3d.cpp index 7a7eec517..d6ab539e0 100644 --- a/src/osgPlugins/ac/ac3d.cpp +++ b/src/osgPlugins/ac/ac3d.cpp @@ -326,16 +326,22 @@ class TextureData { public: TextureData() : - mTranslucent(false) + mTranslucent(false), + mRepeat(false) { } - bool setTexture(const std::string& name, const osgDB::ReaderWriter::Options* options) + bool setTexture(const std::string& name, const osgDB::ReaderWriter::Options* options, osg::TexEnv* modulateTexEnv) { - mTexture2D = new osg::Texture2D; - mTexture2D->setDataVariance(osg::Object::STATIC); - mTexture2D->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT); - mTexture2D->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT); + mTexture2DRepeat = new osg::Texture2D; + mTexture2DRepeat->setDataVariance(osg::Object::STATIC); + mTexture2DRepeat->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT); + mTexture2DRepeat->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT); + + mTexture2DClamp = new osg::Texture2D; + mTexture2DClamp->setDataVariance(osg::Object::STATIC); + mTexture2DClamp->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE); + mTexture2DClamp->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE); std::string absFileName = osgDB::findDataFile(name, options); if (absFileName.empty()) @@ -349,10 +355,19 @@ class TextureData osg::notify(osg::FATAL) << "osgDB ac3d reader: could not read texture \"" << name << "\"" << std::endl; return false; } - mTexture2D->setImage(mImage.get()); + mTexture2DRepeat->setImage(mImage.get()); + mTexture2DClamp->setImage(mImage.get()); mTranslucent = mImage->isImageTranslucent(); + + // Use a shared modulate TexEnv + mModulateTexEnv = modulateTexEnv; + return true; } + void setRepeat(bool repeat) + { + mRepeat = repeat; + } bool valid() const { return mImage.valid(); @@ -367,19 +382,22 @@ class TextureData { if (!valid()) return; - osg::TexEnv* texEnv = new osg::TexEnv; - texEnv->setDataVariance(osg::Object::STATIC); - texEnv->setMode(osg::TexEnv::MODULATE); - stateSet->setTextureAttribute(0, texEnv); - stateSet->setTextureAttribute(0, mTexture2D.get()); + stateSet->setTextureAttribute(0, mModulateTexEnv.get()); + if (mRepeat) + stateSet->setTextureAttribute(0, mTexture2DRepeat.get()); + else + stateSet->setTextureAttribute(0, mTexture2DClamp.get()); stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); if (mTranslucent) setTranslucent(stateSet); } private: - osg::ref_ptr mTexture2D; + osg::ref_ptr mModulateTexEnv; + osg::ref_ptr mTexture2DClamp; + osg::ref_ptr mTexture2DRepeat; osg::ref_ptr mImage; bool mTranslucent; + bool mRepeat; }; class FileData @@ -388,13 +406,17 @@ class FileData FileData(const osgDB::ReaderWriter::Options* options) : mOptions(options), mLightIndex(1) - { } + { + mModulateTexEnv = new osg::TexEnv; + mModulateTexEnv->setDataVariance(osg::Object::STATIC); + mModulateTexEnv->setMode(osg::TexEnv::MODULATE); + } TextureData toTextureData(const std::string& texName) { TextureDataMap::iterator i = mTextureStates.find(texName); if (i == mTextureStates.end()) - mTextureStates[texName].setTexture(texName, mOptions.get()); + mTextureStates[texName].setTexture(texName, mOptions.get(), mModulateTexEnv.get()); return mTextureStates[texName]; } @@ -430,6 +452,8 @@ private: /// ... images are usualy cached in the registries object cache typedef std::map TextureDataMap; TextureDataMap mTextureStates; + /// A common shared TexEnv set to modulate + osg::ref_ptr mModulateTexEnv; /// Hack to include light nodes from ac3d into the scenegraph unsigned mLightIndex; @@ -1152,10 +1176,12 @@ readObject(std::istream& stream, FileData& fileData, const osg::Matrix& parentTr texname = texname.substr(p+1, std::string::npos); } - textureData = fileData.toTextureData(texname); + textureData = fileData.toTextureData(texname); + textureData.setRepeat(false); } else if (token == "texrep") { stream >> textureRepeat[0] >> textureRepeat[1]; + textureData.setRepeat(true); } else if (token == "texoff") { stream >> textureOffset[0] >> textureOffset[1];