diff --git a/include/osgFX/MultiTextureControl b/include/osgFX/MultiTextureControl index 7cb65d4e4..cdff281c5 100644 --- a/include/osgFX/MultiTextureControl +++ b/include/osgFX/MultiTextureControl @@ -32,15 +32,15 @@ namespace osgFX META_Node(osgFX, MultiTextureControl); - typedef std::vector TextureWeightList; + typedef osg::FloatArray TextureWeights; - void setTextureWeights(const TextureWeightList& twl) { _textureWeightList = twl; } - TextureWeightList& getTextureWeights() { return _textureWeightList; } - const TextureWeightList& getTextureWeights() const { return _textureWeightList; } + void setTextureWeights(TextureWeights* twl) { _textureWeights = twl; } + TextureWeights* getTextureWeights() { return _textureWeights.get(); } + const TextureWeights* getTextureWeights() const { return _textureWeights.get(); } void setTextureWeight(unsigned int unit, float weight); - float getTextureWeight(unsigned int unit) const { return (unit<_textureWeightList.size()) ? _textureWeightList[unit] : 0.0f; } - unsigned int getNumTextureWeights() const { return _textureWeightList.size(); } + float getTextureWeight(unsigned int unit) const { return (unit<_textureWeights->size()) ? (*_textureWeights)[unit] : 0.0f; } + unsigned int getNumTextureWeights() const { return _textureWeights->size(); } void setUseTexEnvCombine(bool flag) { _useTexEnvCombine = flag; } bool getUseTexEnvCombine() const { return _useTexEnvCombine; } @@ -49,12 +49,13 @@ namespace osgFX bool getUseTextureWeightsUniform() const { return _useTextureWeightsUniform; } protected: + virtual ~MultiTextureControl() {} MultiTextureControl& operator = (const MultiTextureControl&) { return *this; } void updateStateSet(); - TextureWeightList _textureWeightList; + osg::ref_ptr _textureWeights; bool _useTexEnvCombine; bool _useTextureWeightsUniform; diff --git a/src/osgFX/MultiTextureControl.cpp b/src/osgFX/MultiTextureControl.cpp index dfdbb319b..3edc3c317 100644 --- a/src/osgFX/MultiTextureControl.cpp +++ b/src/osgFX/MultiTextureControl.cpp @@ -23,11 +23,12 @@ MultiTextureControl::MultiTextureControl(): _useTexEnvCombine(true), _useTextureWeightsUniform(true) { + _textureWeights = new TextureWeights; } MultiTextureControl::MultiTextureControl(const MultiTextureControl& copy, const osg::CopyOp& copyop): Group(copy,copyop), - _textureWeightList(copy._textureWeightList), + _textureWeights(osg::clone(copy._textureWeights.get(), osg::CopyOp::DEEP_COPY_ALL)), _useTexEnvCombine(copy._useTexEnvCombine), _useTextureWeightsUniform(copy._useTextureWeightsUniform) { @@ -36,11 +37,11 @@ MultiTextureControl::MultiTextureControl(const MultiTextureControl& copy, const void MultiTextureControl::setTextureWeight(unsigned int unit, float weight) { - if (unit >= _textureWeightList.size()) + if (unit >= _textureWeights->size()) { - _textureWeightList.resize(unit+1,0.0f); + _textureWeights->resize(unit+1,0.0f); } - _textureWeightList[unit] = weight; + (*_textureWeights)[unit] = weight; updateStateSet(); } @@ -53,16 +54,16 @@ void MultiTextureControl::updateStateSet() { unsigned int numTextureUnitsOn = 0; unsigned int unit; - for(unit=0;unit<_textureWeightList.size();++unit) + for(unit=0;unit<_textureWeights->size();++unit) { - if (_textureWeightList[unit]>0.0f) ++numTextureUnitsOn; + if ((*_textureWeights)[unit]>0.0f) ++numTextureUnitsOn; } if (numTextureUnitsOn<=1) { - for(unit=0;unit<_textureWeightList.size();++unit) + for(unit=0;unit<_textureWeights->size();++unit) { - if (_textureWeightList[unit]>0.0f) + if ((*_textureWeights)[unit]>0.0f) { osg::TexEnv* texenv = new osg::TexEnv(osg::TexEnv::MODULATE); stateset->setTextureAttribute(unit, texenv); @@ -75,7 +76,7 @@ void MultiTextureControl::updateStateSet() } } - else if (_textureWeightList.size()==2) + else if (_textureWeights->size()==2) { { osg::TexEnvCombine* texenv = new osg::TexEnvCombine; @@ -87,7 +88,7 @@ void MultiTextureControl::updateStateSet() texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR); - float r = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]); + float r = (*_textureWeights)[0]/((*_textureWeights)[0]+(*_textureWeights)[1]); texenv->setConstantColor(osg::Vec4(r,r,r,r)); stateset->setTextureAttribute(0, texenv); @@ -104,10 +105,10 @@ void MultiTextureControl::updateStateSet() stateset->setTextureAttribute(1, texenv); } } - else if (_textureWeightList.size()==3) + else if (_textureWeights->size()==3) { - float b = (_textureWeightList[0]+_textureWeightList[1])/(_textureWeightList[0]+_textureWeightList[1]+_textureWeightList[2]); - float a = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]); + float b = ((*_textureWeights)[0]+(*_textureWeights)[1])/((*_textureWeights)[0]+(*_textureWeights)[1]+(*_textureWeights)[2]); + float a = (*_textureWeights)[0]/((*_textureWeights)[0]+(*_textureWeights)[1]); { osg::TexEnvCombine* texenv = new osg::TexEnvCombine; @@ -152,13 +153,17 @@ void MultiTextureControl::updateStateSet() } } - if (_useTextureWeightsUniform && _textureWeightList.size()>0) + if (_useTextureWeightsUniform && _textureWeights->size()>0) { - osg::ref_ptr uniform = new osg::Uniform(osg::Uniform::FLOAT, "TextureWeights", _textureWeightList.size()); - for(unsigned int i=0; i<_textureWeightList.size(); ++i) + osg::ref_ptr uniform = new osg::Uniform(osg::Uniform::FLOAT, "TextureWeights", _textureWeights->size()); +#if 1 + uniform->setArray(_textureWeights.get()); +#else + for(unsigned int i=0; i<_textureWeights->size(); ++i) { - uniform->setElement(i, _textureWeightList[i]); + uniform->setElement(i, (*_textureWeights)[i]); } +#endif stateset->addUniform(uniform.get()); } diff --git a/src/osgWrappers/serializers/osgFX/MultiTextureControl.cpp b/src/osgWrappers/serializers/osgFX/MultiTextureControl.cpp index d9fd9d349..1355263c1 100644 --- a/src/osgWrappers/serializers/osgFX/MultiTextureControl.cpp +++ b/src/osgWrappers/serializers/osgFX/MultiTextureControl.cpp @@ -3,14 +3,48 @@ #include #include +static bool checkTextureWeights( const osgFX::MultiTextureControl& ctrl ) +{ + return ctrl.getNumTextureWeights()>0; +} + +static bool readTextureWeights( osgDB::InputStream& is, osgFX::MultiTextureControl& ctrl ) +{ + unsigned int size = is.readSize(); is >> is.BEGIN_BRACKET; + for ( unsigned int i=0; i> weight; + ctrl.setTextureWeight( i, weight ); + } + is >> is.END_BRACKET; + return true; +} + +static bool writeTextureWeights( osgDB::OutputStream& os, const osgFX::MultiTextureControl& ctrl ) +{ + unsigned int size = ctrl.getNumTextureWeights(); + os.writeSize(size); os << os.BEGIN_BRACKET << std::endl; + for ( unsigned int i=0; i