Add positioned uniforms and G-buffer textures to Effects
This commit is contained in:
@@ -916,6 +916,7 @@ struct UniformBuilder :public PassAttributeBuilder
|
|||||||
return;
|
return;
|
||||||
const SGPropertyNode* nameProp = prop->getChild("name");
|
const SGPropertyNode* nameProp = prop->getChild("name");
|
||||||
const SGPropertyNode* typeProp = prop->getChild("type");
|
const SGPropertyNode* typeProp = prop->getChild("type");
|
||||||
|
const SGPropertyNode* positionedProp = prop->getChild("positioned");
|
||||||
const SGPropertyNode* valProp = prop->getChild("value");
|
const SGPropertyNode* valProp = prop->getChild("value");
|
||||||
string name;
|
string name;
|
||||||
Uniform::Type uniformType = Uniform::FLOAT;
|
Uniform::Type uniformType = Uniform::FLOAT;
|
||||||
@@ -1003,6 +1004,11 @@ struct UniformBuilder :public PassAttributeBuilder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pass->addUniform(uniform.get());
|
pass->addUniform(uniform.get());
|
||||||
|
if (positionedProp && positionedProp->getBoolValue() && uniformType == Uniform::FLOAT_VEC4) {
|
||||||
|
osg::Vec4 offset;
|
||||||
|
uniform->get(offset);
|
||||||
|
pass->addPositionedUniform( name, offset );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1163,7 +1169,10 @@ struct DepthBuilder : public PassAttributeBuilder
|
|||||||
= getEffectPropertyChild(effect, prop, "write-mask");
|
= getEffectPropertyChild(effect, prop, "write-mask");
|
||||||
if (pmask)
|
if (pmask)
|
||||||
depth->setWriteMask(pmask->getValue<bool>());
|
depth->setWriteMask(pmask->getValue<bool>());
|
||||||
pass->setAttribute(depth.get());
|
const SGPropertyNode* penabled
|
||||||
|
= getEffectPropertyChild(effect, prop, "enabled");
|
||||||
|
bool enabled = ( penabled == 0 || penabled->getBoolValue() );
|
||||||
|
pass->setAttributeAndModes(depth.get(), enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -58,16 +58,16 @@ class EffectBuilder : public SGReferenced
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~EffectBuilder() {}
|
virtual ~EffectBuilder() {}
|
||||||
virtual T* build(Effect* effect, const SGPropertyNode*,
|
virtual T* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||||
const SGReaderWriterOptions* options) = 0;
|
const SGReaderWriterOptions* options) = 0;
|
||||||
static T* buildFromType(Effect* effect, const std::string& type,
|
static T* buildFromType(Effect* effect, Pass* pass, const std::string& type,
|
||||||
const SGPropertyNode*props,
|
const SGPropertyNode*props,
|
||||||
const SGReaderWriterOptions* options)
|
const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
BuilderMap& builderMap = getMap();
|
BuilderMap& builderMap = getMap();
|
||||||
typename BuilderMap::iterator iter = builderMap.find(type);
|
typename BuilderMap::iterator iter = builderMap.find(type);
|
||||||
if (iter != builderMap.end())
|
if (iter != builderMap.end())
|
||||||
return iter->second->build(effect, props, options);
|
return iter->second->build(effect, pass, props, options);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <osg/StateSet>
|
#include <osg/StateSet>
|
||||||
|
#include <osg/Texture2D>
|
||||||
|
|
||||||
#include "EffectCullVisitor.hxx"
|
#include "EffectCullVisitor.hxx"
|
||||||
|
|
||||||
@@ -78,4 +79,20 @@ void EffectCullVisitor::apply(osg::Geode& node)
|
|||||||
popStateSet();
|
popStateSet();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EffectCullVisitor::clearBufferList()
|
||||||
|
{
|
||||||
|
_bufferList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectCullVisitor::addBuffer(int i, osg::Texture2D* tex)
|
||||||
|
{
|
||||||
|
_bufferList.insert(std::make_pair(i,tex));
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Texture2D* EffectCullVisitor::getBuffer(int i)
|
||||||
|
{
|
||||||
|
return _bufferList[i];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,12 @@
|
|||||||
|
|
||||||
#include <osgUtil/CullVisitor>
|
#include <osgUtil/CullVisitor>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Geode;
|
class Geode;
|
||||||
|
class Texture2D;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace simgear
|
namespace simgear
|
||||||
@@ -34,6 +37,13 @@ public:
|
|||||||
virtual osgUtil::CullVisitor* clone() const;
|
virtual osgUtil::CullVisitor* clone() const;
|
||||||
using osgUtil::CullVisitor::apply;
|
using osgUtil::CullVisitor::apply;
|
||||||
virtual void apply(osg::Geode& node);
|
virtual void apply(osg::Geode& node);
|
||||||
|
|
||||||
|
void clearBufferList();
|
||||||
|
void addBuffer(int i, osg::Texture2D* tex);
|
||||||
|
osg::Texture2D* getBuffer(int i);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<int,osg::ref_ptr<osg::Texture2D> > _bufferList;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,10 +26,23 @@ namespace simgear
|
|||||||
class Pass : public osg::StateSet
|
class Pass : public osg::StateSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef std::list<std::pair<int,int> > BufferUnitList;
|
||||||
|
typedef std::map<std::string,osg::Vec4> PositionedUniformMap;
|
||||||
|
|
||||||
META_Object(simgear,Pass);
|
META_Object(simgear,Pass);
|
||||||
Pass() {}
|
Pass() {}
|
||||||
Pass(const Pass& rhs,
|
Pass(const Pass& rhs,
|
||||||
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
|
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
|
||||||
|
|
||||||
|
void setBufferUnit( int unit, int buffer ) { _bufferUnitList.push_back( std::make_pair(unit,buffer) ); }
|
||||||
|
const BufferUnitList& getBufferUnitList() const { return _bufferUnitList; }
|
||||||
|
|
||||||
|
void addPositionedUniform( const std::string& name, const osg::Vec4& offset ) { _positionedUniforms[name] = offset; }
|
||||||
|
const PositionedUniformMap& getPositionedUniformMap() const { return _positionedUniforms; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
BufferUnitList _bufferUnitList;
|
||||||
|
PositionedUniformMap _positionedUniforms;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "Technique.hxx"
|
#include "Technique.hxx"
|
||||||
#include "Pass.hxx"
|
#include "Pass.hxx"
|
||||||
|
#include "EffectCullVisitor.hxx"
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
@@ -15,6 +16,8 @@
|
|||||||
#include <osg/GLExtensions>
|
#include <osg/GLExtensions>
|
||||||
#include <osg/GL2Extensions>
|
#include <osg/GL2Extensions>
|
||||||
#include <osg/Math>
|
#include <osg/Math>
|
||||||
|
#include <osg/Texture2D>
|
||||||
|
#include <osg/CopyOp>
|
||||||
#include <osgUtil/CullVisitor>
|
#include <osgUtil/CullVisitor>
|
||||||
|
|
||||||
#include <osgDB/Registry>
|
#include <osgDB/Registry>
|
||||||
@@ -159,10 +162,37 @@ Technique::processDrawables(const EffectGeode::DrawablesIterator& begin,
|
|||||||
if (isNaN(depth[i]))
|
if (isNaN(depth[i]))
|
||||||
depth[i] = FLT_MAX;
|
depth[i] = FLT_MAX;
|
||||||
}
|
}
|
||||||
|
EffectCullVisitor* ecv = dynamic_cast<EffectCullVisitor*>( cv );
|
||||||
EffectGeode::DrawablesIterator drawablesEnd = itr;
|
EffectGeode::DrawablesIterator drawablesEnd = itr;
|
||||||
BOOST_FOREACH(ref_ptr<Pass>& pass, passes)
|
BOOST_FOREACH(ref_ptr<Pass>& pass, passes)
|
||||||
{
|
{
|
||||||
cv->pushStateSet(pass.get());
|
osg::ref_ptr<osg::StateSet> ss = pass;
|
||||||
|
if (ecv && ( pass->getBufferUnitList().size() != 0 || pass->getPositionedUniformMap().size() != 0 ) ) {
|
||||||
|
ss = static_cast<osg::StateSet*>(
|
||||||
|
pass->clone( osg::CopyOp( ( pass->getBufferUnitList().size() != 0 ?
|
||||||
|
osg::CopyOp::DEEP_COPY_TEXTURES :
|
||||||
|
osg::CopyOp::SHALLOW_COPY ) |
|
||||||
|
( pass->getPositionedUniformMap().size() != 0 ?
|
||||||
|
osg::CopyOp::DEEP_COPY_UNIFORMS :
|
||||||
|
osg::CopyOp::SHALLOW_COPY ) )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
for (Pass::BufferUnitList::const_iterator ii = pass->getBufferUnitList().begin();
|
||||||
|
ii != pass->getBufferUnitList().end();
|
||||||
|
++ii) {
|
||||||
|
osg::Texture2D* tex = ecv->getBuffer(ii->second);
|
||||||
|
if (tex != 0)
|
||||||
|
ss->setTextureAttributeAndModes( ii->first, tex );
|
||||||
|
}
|
||||||
|
for (Pass::PositionedUniformMap::const_iterator ii = pass->getPositionedUniformMap().begin();
|
||||||
|
ii != pass->getPositionedUniformMap().end();
|
||||||
|
++ii) {
|
||||||
|
osg::RefMatrix* mv = cv->getModelViewMatrix();
|
||||||
|
osg::Vec4 v = ii->second * *mv;
|
||||||
|
ss->getUniform(ii->first)->set( v );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cv->pushStateSet(ss);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (itr = begin; itr != drawablesEnd; ++itr, ++i) {
|
for (itr = begin; itr != drawablesEnd; ++itr, ++i) {
|
||||||
if (depth[i] != FLT_MAX)
|
if (depth[i] != FLT_MAX)
|
||||||
|
|||||||
@@ -59,12 +59,12 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect,
|
|||||||
TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp);
|
TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp);
|
||||||
|
|
||||||
// Hack to force inclusion of TextureBuilder.cxx in library
|
// Hack to force inclusion of TextureBuilder.cxx in library
|
||||||
osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type,
|
osg::Texture* TextureBuilder::buildFromType(Effect* effect, Pass* pass, const string& type,
|
||||||
const SGPropertyNode*props,
|
const SGPropertyNode*props,
|
||||||
const SGReaderWriterOptions*
|
const SGReaderWriterOptions*
|
||||||
options)
|
options)
|
||||||
{
|
{
|
||||||
return EffectBuilder<Texture>::buildFromType(effect, type, props, options);
|
return EffectBuilder<Texture>::buildFromType(effect, pass, type, props, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef boost::tuple<string, Texture::FilterMode, Texture::FilterMode,
|
typedef boost::tuple<string, Texture::FilterMode, Texture::FilterMode,
|
||||||
@@ -130,7 +130,7 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
|
|||||||
type = pType->getStringValue();
|
type = pType->getStringValue();
|
||||||
Texture* texture = 0;
|
Texture* texture = 0;
|
||||||
try {
|
try {
|
||||||
texture = TextureBuilder::buildFromType(effect, type, prop,
|
texture = TextureBuilder::buildFromType(effect, pass, type, prop,
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
catch (BuilderException& e) {
|
catch (BuilderException& e) {
|
||||||
@@ -278,7 +278,7 @@ class TexBuilder : public TextureBuilder
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TexBuilder(const string& texType) : _type(texType) {}
|
TexBuilder(const string& texType) : _type(texType) {}
|
||||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||||
const SGReaderWriterOptions* options);
|
const SGReaderWriterOptions* options);
|
||||||
protected:
|
protected:
|
||||||
typedef map<TexTuple, ref_ptr<T> > TexMap;
|
typedef map<TexTuple, ref_ptr<T> > TexMap;
|
||||||
@@ -287,7 +287,7 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Texture* TexBuilder<T>::build(Effect* effect, const SGPropertyNode* props,
|
Texture* TexBuilder<T>::build(Effect* effect, Pass* pass, const SGPropertyNode* props,
|
||||||
const SGReaderWriterOptions* options)
|
const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
TexTuple attrs = makeTexTuple(effect, props, options, _type);
|
TexTuple attrs = makeTexTuple(effect, props, options, _type);
|
||||||
@@ -311,11 +311,11 @@ TextureBuilder::Registrar install3D("3d", new TexBuilder<Texture3D>("3d"));
|
|||||||
class WhiteTextureBuilder : public TextureBuilder
|
class WhiteTextureBuilder : public TextureBuilder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||||
const SGReaderWriterOptions* options);
|
const SGReaderWriterOptions* options);
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture* WhiteTextureBuilder::build(Effect* effect, const SGPropertyNode*,
|
Texture* WhiteTextureBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||||
const SGReaderWriterOptions* options)
|
const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
return StateAttributeFactory::instance()->getWhiteTexture();
|
return StateAttributeFactory::instance()->getWhiteTexture();
|
||||||
@@ -329,11 +329,11 @@ TextureBuilder::Registrar installWhite("white", new WhiteTextureBuilder);
|
|||||||
class TransparentTextureBuilder : public TextureBuilder
|
class TransparentTextureBuilder : public TextureBuilder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||||
const SGReaderWriterOptions* options);
|
const SGReaderWriterOptions* options);
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture* TransparentTextureBuilder::build(Effect* effect, const SGPropertyNode*,
|
Texture* TransparentTextureBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||||
const SGReaderWriterOptions* options)
|
const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
return StateAttributeFactory::instance()->getTransparentTexture();
|
return StateAttributeFactory::instance()->getTransparentTexture();
|
||||||
@@ -393,14 +393,14 @@ osg::Image* make3DNoiseImage(int texSize)
|
|||||||
class NoiseBuilder : public TextureBuilder
|
class NoiseBuilder : public TextureBuilder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||||
const SGReaderWriterOptions* options);
|
const SGReaderWriterOptions* options);
|
||||||
protected:
|
protected:
|
||||||
typedef map<int, ref_ptr<Texture3D> > NoiseMap;
|
typedef map<int, ref_ptr<Texture3D> > NoiseMap;
|
||||||
NoiseMap _noises;
|
NoiseMap _noises;
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture* NoiseBuilder::build(Effect* effect, const SGPropertyNode* props,
|
Texture* NoiseBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* props,
|
||||||
const SGReaderWriterOptions* options)
|
const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
int texSize = 64;
|
int texSize = 64;
|
||||||
@@ -461,7 +461,7 @@ CubeMapTuple makeCubeMapTuple(Effect* effect, const SGPropertyNode* props)
|
|||||||
class CubeMapBuilder : public TextureBuilder
|
class CubeMapBuilder : public TextureBuilder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||||
const SGReaderWriterOptions* options);
|
const SGReaderWriterOptions* options);
|
||||||
protected:
|
protected:
|
||||||
typedef map<CubeMapTuple, ref_ptr<TextureCubeMap> > CubeMap;
|
typedef map<CubeMapTuple, ref_ptr<TextureCubeMap> > CubeMap;
|
||||||
@@ -484,7 +484,7 @@ void copySubImage(const osg::Image* srcImage, int src_s, int src_t, int width, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Texture* CubeMapBuilder::build(Effect* effect, const SGPropertyNode* props,
|
Texture* CubeMapBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* props,
|
||||||
const SGReaderWriterOptions* options)
|
const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
// First check that there is a <images> tag
|
// First check that there is a <images> tag
|
||||||
@@ -876,4 +876,45 @@ bool makeTextureParameters(SGPropertyNode* paramRoot, const StateSet* ss)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GBufferBuilder : public TextureBuilder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GBufferBuilder(int b) : buffer(b) {}
|
||||||
|
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||||
|
const SGReaderWriterOptions* options);
|
||||||
|
private:
|
||||||
|
int buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture* GBufferBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* prop,
|
||||||
|
const SGReaderWriterOptions* options)
|
||||||
|
{
|
||||||
|
int unit = 0;
|
||||||
|
const SGPropertyNode* pUnit = prop->getChild("unit");
|
||||||
|
if (pUnit) {
|
||||||
|
unit = pUnit->getValue<int>();
|
||||||
|
} else {
|
||||||
|
const SGPropertyNode* pName = prop->getChild("name");
|
||||||
|
if (pName)
|
||||||
|
try {
|
||||||
|
unit = boost::lexical_cast<int>(pName->getStringValue());
|
||||||
|
} catch (boost::bad_lexical_cast& lex) {
|
||||||
|
SG_LOG(SG_INPUT, SG_ALERT, "can't decode name as texture unit "
|
||||||
|
<< lex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pass->setBufferUnit( unit, buffer );
|
||||||
|
|
||||||
|
// Return white for now. Would be overridden in Technique::ProcessDrawable
|
||||||
|
return StateAttributeFactory::instance()->getWhiteTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
TextureBuilder::Registrar installDepthBuffer("depth-buffer", new GBufferBuilder(0));
|
||||||
|
TextureBuilder::Registrar installNormalBuffer("normal-buffer", new GBufferBuilder(1));
|
||||||
|
TextureBuilder::Registrar installDiffuseBuffer("diffuse-buffer", new GBufferBuilder(2));
|
||||||
|
TextureBuilder::Registrar installSpecularBuffer("specular-buffer", new GBufferBuilder(3));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class TextureBuilder : public EffectBuilder<osg::Texture>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Hack to force inclusion of TextureBuilder.cxx in library
|
// Hack to force inclusion of TextureBuilder.cxx in library
|
||||||
static osg::Texture* buildFromType(Effect* effect, const std::string& type,
|
static osg::Texture* buildFromType(Effect* effect, Pass* pass, const std::string& type,
|
||||||
const SGPropertyNode*props,
|
const SGPropertyNode*props,
|
||||||
const SGReaderWriterOptions* options);
|
const SGReaderWriterOptions* options);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user