From 7fbeeefea878cf280dd7050baa993fb587e1c0cb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 21 Jan 2015 11:09:29 +0000 Subject: [PATCH] Added TextureWeights uniform support and controls to osgFX::MultiTextureControl to support usage with shaders. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14668 16af8721-9629-0410-8352-f15c8da7e697 --- include/osgFX/MultiTextureControl | 19 +- src/osgFX/MultiTextureControl.cpp | 181 ++++++++++-------- src/osgTerrain/GeometryTechnique.cpp | 1 - .../serializers/osgFX/MultiTextureControl.cpp | 36 +--- 4 files changed, 121 insertions(+), 116 deletions(-) diff --git a/include/osgFX/MultiTextureControl b/include/osgFX/MultiTextureControl index 659b1ddf9..7cb65d4e4 100644 --- a/include/osgFX/MultiTextureControl +++ b/include/osgFX/MultiTextureControl @@ -32,20 +32,33 @@ namespace osgFX META_Node(osgFX, MultiTextureControl); + typedef std::vector TextureWeightList; + + void setTextureWeights(const TextureWeightList& twl) { _textureWeightList = twl; } + TextureWeightList& getTextureWeights() { return _textureWeightList; } + const TextureWeightList& getTextureWeights() const { return _textureWeightList; } + 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(); } + void setUseTexEnvCombine(bool flag) { _useTexEnvCombine = flag; } + bool getUseTexEnvCombine() const { return _useTexEnvCombine; } + + void setUseTextureWeightsUniform(bool flag) { _useTextureWeightsUniform = flag; } + bool getUseTextureWeightsUniform() const { return _useTextureWeightsUniform; } + protected: virtual ~MultiTextureControl() {} MultiTextureControl& operator = (const MultiTextureControl&) { return *this; } void updateStateSet(); - typedef std::vector TextureWeightList; TextureWeightList _textureWeightList; + + bool _useTexEnvCombine; + bool _useTextureWeightsUniform; + }; } diff --git a/src/osgFX/MultiTextureControl.cpp b/src/osgFX/MultiTextureControl.cpp index a357f8205..dfdbb319b 100644 --- a/src/osgFX/MultiTextureControl.cpp +++ b/src/osgFX/MultiTextureControl.cpp @@ -19,13 +19,17 @@ using namespace osg; using namespace osgFX; -MultiTextureControl::MultiTextureControl() +MultiTextureControl::MultiTextureControl(): + _useTexEnvCombine(true), + _useTextureWeightsUniform(true) { } MultiTextureControl::MultiTextureControl(const MultiTextureControl& copy, const osg::CopyOp& copyop): Group(copy,copyop), - _textureWeightList(copy._textureWeightList) + _textureWeightList(copy._textureWeightList), + _useTexEnvCombine(copy._useTexEnvCombine), + _useTextureWeightsUniform(copy._useTextureWeightsUniform) { updateStateSet(); } @@ -45,104 +49,117 @@ void MultiTextureControl::updateStateSet() { osg::ref_ptr stateset = new osg::StateSet; - unsigned int numTextureUnitsOn = 0; - unsigned int unit; - for(unit=0;unit<_textureWeightList.size();++unit) - { - if (_textureWeightList[unit]>0.0f) ++numTextureUnitsOn; - } - - if (numTextureUnitsOn<=1) + if (_useTexEnvCombine) { + unsigned int numTextureUnitsOn = 0; + unsigned int unit; for(unit=0;unit<_textureWeightList.size();++unit) { - if (_textureWeightList[unit]>0.0f) + if (_textureWeightList[unit]>0.0f) ++numTextureUnitsOn; + } + + if (numTextureUnitsOn<=1) + { + for(unit=0;unit<_textureWeightList.size();++unit) { - osg::TexEnv* texenv = new osg::TexEnv(osg::TexEnv::MODULATE); - stateset->setTextureAttribute(unit, texenv); - stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::ON); + if (_textureWeightList[unit]>0.0f) + { + osg::TexEnv* texenv = new osg::TexEnv(osg::TexEnv::MODULATE); + stateset->setTextureAttribute(unit, texenv); + stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::ON); + } + else + { + stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); + } } - else + + } + else if (_textureWeightList.size()==2) + { { - stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); + osg::TexEnvCombine* texenv = new osg::TexEnvCombine; + texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE0+0); + texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); + texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+1); + texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); + texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); + texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR); + + float r = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]); + texenv->setConstantColor(osg::Vec4(r,r,r,r)); + + stateset->setTextureAttribute(0, texenv); + } + + { + osg::TexEnvCombine* texenv = new osg::TexEnvCombine; + texenv->setCombine_RGB(osg::TexEnvCombine::MODULATE); + texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); + texenv->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR); + texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); + + stateset->setTextureAttribute(1, texenv); } } - - } - else if (_textureWeightList.size()==2) - { + else if (_textureWeightList.size()==3) { - osg::TexEnvCombine* texenv = new osg::TexEnvCombine; - texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); - texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE0+0); - texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); - texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+1); - texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); - texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); - texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR); + float b = (_textureWeightList[0]+_textureWeightList[1])/(_textureWeightList[0]+_textureWeightList[1]+_textureWeightList[2]); + float a = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]); - float r = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]); - texenv->setConstantColor(osg::Vec4(r,r,r,r)); + { + osg::TexEnvCombine* texenv = new osg::TexEnvCombine; + texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE0+0); + texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); + texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+1); + texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); + texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); + texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR); - stateset->setTextureAttribute(0, texenv); - } + texenv->setConstantColor(osg::Vec4(a,a,a,a)); - { - osg::TexEnvCombine* texenv = new osg::TexEnvCombine; - texenv->setCombine_RGB(osg::TexEnvCombine::MODULATE); - texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); - texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); - texenv->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR); - texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); + stateset->setTextureAttribute(0, texenv); + } - stateset->setTextureAttribute(1, texenv); + { + osg::TexEnvCombine* texenv = new osg::TexEnvCombine; + texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); + texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+2); + texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); + texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); + texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR); + + texenv->setConstantColor(osg::Vec4(b,b,b,b)); + + stateset->setTextureAttribute(1, texenv); + } + + { + osg::TexEnvCombine* texenv = new osg::TexEnvCombine; + texenv->setCombine_RGB(osg::TexEnvCombine::MODULATE); + texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); + texenv->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR); + texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); + + stateset->setTextureAttribute(2, texenv); + } } } - else if (_textureWeightList.size()==3) + + if (_useTextureWeightsUniform && _textureWeightList.size()>0) { - float b = (_textureWeightList[0]+_textureWeightList[1])/(_textureWeightList[0]+_textureWeightList[1]+_textureWeightList[2]); - float a = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]); - + osg::ref_ptr uniform = new osg::Uniform(osg::Uniform::FLOAT, "TextureWeights", _textureWeightList.size()); + for(unsigned int i=0; i<_textureWeightList.size(); ++i) { - osg::TexEnvCombine* texenv = new osg::TexEnvCombine; - texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); - texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE0+0); - texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); - texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+1); - texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); - texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); - texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR); - - texenv->setConstantColor(osg::Vec4(a,a,a,a)); - - stateset->setTextureAttribute(0, texenv); - } - - { - osg::TexEnvCombine* texenv = new osg::TexEnvCombine; - texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); - texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); - texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); - texenv->setSource1_RGB(osg::TexEnvCombine::TEXTURE0+2); - texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); - texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); - texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR); - - texenv->setConstantColor(osg::Vec4(b,b,b,b)); - - stateset->setTextureAttribute(1, texenv); - } - - { - osg::TexEnvCombine* texenv = new osg::TexEnvCombine; - texenv->setCombine_RGB(osg::TexEnvCombine::MODULATE); - texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); - texenv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR); - texenv->setSource1_RGB(osg::TexEnvCombine::PRIMARY_COLOR); - texenv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR); - - stateset->setTextureAttribute(2, texenv); + uniform->setElement(i, _textureWeightList[i]); } + stateset->addUniform(uniform.get()); } setStateSet(stateset.get()); diff --git a/src/osgTerrain/GeometryTechnique.cpp b/src/osgTerrain/GeometryTechnique.cpp index e1c461b94..53044979a 100644 --- a/src/osgTerrain/GeometryTechnique.cpp +++ b/src/osgTerrain/GeometryTechnique.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/src/osgWrappers/serializers/osgFX/MultiTextureControl.cpp b/src/osgWrappers/serializers/osgFX/MultiTextureControl.cpp index 7b4786c6e..d9fd9d349 100644 --- a/src/osgWrappers/serializers/osgFX/MultiTextureControl.cpp +++ b/src/osgWrappers/serializers/osgFX/MultiTextureControl.cpp @@ -3,39 +3,15 @@ #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