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
This commit is contained in:
Robert Osfield
2015-01-21 11:09:29 +00:00
parent 3ab06c54bf
commit 7fbeeefea8
4 changed files with 121 additions and 116 deletions

View File

@@ -32,20 +32,33 @@ namespace osgFX
META_Node(osgFX, MultiTextureControl); META_Node(osgFX, MultiTextureControl);
typedef std::vector<float> 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); void setTextureWeight(unsigned int unit, float weight);
float getTextureWeight(unsigned int unit) const { return (unit<_textureWeightList.size()) ? _textureWeightList[unit] : 0.0f; } float getTextureWeight(unsigned int unit) const { return (unit<_textureWeightList.size()) ? _textureWeightList[unit] : 0.0f; }
unsigned int getNumTextureWeights() const { return _textureWeightList.size(); } 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: protected:
virtual ~MultiTextureControl() {} virtual ~MultiTextureControl() {}
MultiTextureControl& operator = (const MultiTextureControl&) { return *this; } MultiTextureControl& operator = (const MultiTextureControl&) { return *this; }
void updateStateSet(); void updateStateSet();
typedef std::vector<float> TextureWeightList;
TextureWeightList _textureWeightList; TextureWeightList _textureWeightList;
bool _useTexEnvCombine;
bool _useTextureWeightsUniform;
}; };
} }

View File

@@ -19,13 +19,17 @@
using namespace osg; using namespace osg;
using namespace osgFX; using namespace osgFX;
MultiTextureControl::MultiTextureControl() MultiTextureControl::MultiTextureControl():
_useTexEnvCombine(true),
_useTextureWeightsUniform(true)
{ {
} }
MultiTextureControl::MultiTextureControl(const MultiTextureControl& copy, const osg::CopyOp& copyop): MultiTextureControl::MultiTextureControl(const MultiTextureControl& copy, const osg::CopyOp& copyop):
Group(copy,copyop), Group(copy,copyop),
_textureWeightList(copy._textureWeightList) _textureWeightList(copy._textureWeightList),
_useTexEnvCombine(copy._useTexEnvCombine),
_useTextureWeightsUniform(copy._useTextureWeightsUniform)
{ {
updateStateSet(); updateStateSet();
} }
@@ -45,104 +49,117 @@ void MultiTextureControl::updateStateSet()
{ {
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet; osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
unsigned int numTextureUnitsOn = 0; if (_useTexEnvCombine)
unsigned int unit;
for(unit=0;unit<_textureWeightList.size();++unit)
{
if (_textureWeightList[unit]>0.0f) ++numTextureUnitsOn;
}
if (numTextureUnitsOn<=1)
{ {
unsigned int numTextureUnitsOn = 0;
unsigned int unit;
for(unit=0;unit<_textureWeightList.size();++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); if (_textureWeightList[unit]>0.0f)
stateset->setTextureAttribute(unit, texenv); {
stateset->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::ON); 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()==3)
}
else if (_textureWeightList.size()==2)
{
{ {
osg::TexEnvCombine* texenv = new osg::TexEnvCombine; float b = (_textureWeightList[0]+_textureWeightList[1])/(_textureWeightList[0]+_textureWeightList[1]+_textureWeightList[2]);
texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); float a = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]);
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)); 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));
}
{ 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); {
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]); osg::ref_ptr<osg::Uniform> uniform = new osg::Uniform(osg::Uniform::FLOAT, "TextureWeights", _textureWeightList.size());
float a = _textureWeightList[0]/(_textureWeightList[0]+_textureWeightList[1]); for(unsigned int i=0; i<_textureWeightList.size(); ++i)
{ {
osg::TexEnvCombine* texenv = new osg::TexEnvCombine; uniform->setElement(i, _textureWeightList[i]);
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);
} }
stateset->addUniform(uniform.get());
} }
setStateSet(stateset.get()); setStateSet(stateset.get());

View File

@@ -22,7 +22,6 @@
#include <osg/io_utils> #include <osg/io_utils>
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osg/Texture1D> #include <osg/Texture1D>
#include <osg/TexEnvCombine>
#include <osg/Program> #include <osg/Program>
#include <osg/Math> #include <osg/Math>
#include <osg/Timer> #include <osg/Timer>

View File

@@ -3,39 +3,15 @@
#include <osgDB/InputStream> #include <osgDB/InputStream>
#include <osgDB/OutputStream> #include <osgDB/OutputStream>
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<size; ++i )
{
float weight = 0.0f; is >> 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<size; ++i )
{
os << ctrl.getTextureWeight(i);
}
os << os.END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( osgFX_MultiTextureControl, REGISTER_OBJECT_WRAPPER( osgFX_MultiTextureControl,
new osgFX::MultiTextureControl, new osgFX::MultiTextureControl,
osgFX::MultiTextureControl, osgFX::MultiTextureControl,
"osg::Object osg::Node osg::Group osgFX::MultiTextureControl" ) "osg::Object osg::Node osg::Group osgFX::MultiTextureControl" )
{ {
ADD_USER_SERIALIZER( TextureWeights ); // _textureWeightList ADD_VECTOR_SERIALIZER( TextureWeights, osgFX::MultiTextureControl::TextureWeightList, osgDB::BaseSerializer::RW_FLOAT, 1.0f );
{
UPDATE_TO_VERSION_SCOPED( 116 )
ADD_BOOL_SERIALIZER( UseTexEnvCombine, true );
ADD_BOOL_SERIALIZER( UseTextureWeightsUniform, true );
}
} }