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:
@@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user