Add positioned uniforms and G-buffer textures to Effects
This commit is contained in:
parent
9700e46e47
commit
d393e4a019
@ -916,6 +916,7 @@ struct UniformBuilder :public PassAttributeBuilder
|
||||
return;
|
||||
const SGPropertyNode* nameProp = prop->getChild("name");
|
||||
const SGPropertyNode* typeProp = prop->getChild("type");
|
||||
const SGPropertyNode* positionedProp = prop->getChild("positioned");
|
||||
const SGPropertyNode* valProp = prop->getChild("value");
|
||||
string name;
|
||||
Uniform::Type uniformType = Uniform::FLOAT;
|
||||
@ -1003,6 +1004,11 @@ struct UniformBuilder :public PassAttributeBuilder
|
||||
}
|
||||
}
|
||||
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");
|
||||
if (pmask)
|
||||
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:
|
||||
virtual ~EffectBuilder() {}
|
||||
virtual T* build(Effect* effect, const SGPropertyNode*,
|
||||
virtual T* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||
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 SGReaderWriterOptions* options)
|
||||
{
|
||||
BuilderMap& builderMap = getMap();
|
||||
typename BuilderMap::iterator iter = builderMap.find(type);
|
||||
if (iter != builderMap.end())
|
||||
return iter->second->build(effect, props, options);
|
||||
return iter->second->build(effect, pass, props, options);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#endif
|
||||
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Texture2D>
|
||||
|
||||
#include "EffectCullVisitor.hxx"
|
||||
|
||||
@ -78,4 +79,20 @@ void EffectCullVisitor::apply(osg::Geode& node)
|
||||
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 <map>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class Geode;
|
||||
class Texture2D;
|
||||
}
|
||||
|
||||
namespace simgear
|
||||
@ -34,6 +37,13 @@ public:
|
||||
virtual osgUtil::CullVisitor* clone() const;
|
||||
using osgUtil::CullVisitor::apply;
|
||||
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
|
||||
|
@ -26,10 +26,23 @@ namespace simgear
|
||||
class Pass : public osg::StateSet
|
||||
{
|
||||
public:
|
||||
typedef std::list<std::pair<int,int> > BufferUnitList;
|
||||
typedef std::map<std::string,osg::Vec4> PositionedUniformMap;
|
||||
|
||||
META_Object(simgear,Pass);
|
||||
Pass() {}
|
||||
Pass(const Pass& rhs,
|
||||
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 "Pass.hxx"
|
||||
#include "EffectCullVisitor.hxx"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
@ -15,6 +16,8 @@
|
||||
#include <osg/GLExtensions>
|
||||
#include <osg/GL2Extensions>
|
||||
#include <osg/Math>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/CopyOp>
|
||||
#include <osgUtil/CullVisitor>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
@ -159,10 +162,37 @@ Technique::processDrawables(const EffectGeode::DrawablesIterator& begin,
|
||||
if (isNaN(depth[i]))
|
||||
depth[i] = FLT_MAX;
|
||||
}
|
||||
EffectCullVisitor* ecv = dynamic_cast<EffectCullVisitor*>( cv );
|
||||
EffectGeode::DrawablesIterator drawablesEnd = itr;
|
||||
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;
|
||||
for (itr = begin; itr != drawablesEnd; ++itr, ++i) {
|
||||
if (depth[i] != FLT_MAX)
|
||||
|
@ -59,12 +59,12 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect,
|
||||
TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp);
|
||||
|
||||
// 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 SGReaderWriterOptions*
|
||||
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,
|
||||
@ -130,7 +130,7 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
|
||||
type = pType->getStringValue();
|
||||
Texture* texture = 0;
|
||||
try {
|
||||
texture = TextureBuilder::buildFromType(effect, type, prop,
|
||||
texture = TextureBuilder::buildFromType(effect, pass, type, prop,
|
||||
options);
|
||||
}
|
||||
catch (BuilderException& e) {
|
||||
@ -278,7 +278,7 @@ class TexBuilder : public TextureBuilder
|
||||
{
|
||||
public:
|
||||
TexBuilder(const string& texType) : _type(texType) {}
|
||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
||||
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||
const SGReaderWriterOptions* options);
|
||||
protected:
|
||||
typedef map<TexTuple, ref_ptr<T> > TexMap;
|
||||
@ -287,7 +287,7 @@ protected:
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
TexTuple attrs = makeTexTuple(effect, props, options, _type);
|
||||
@ -311,11 +311,11 @@ TextureBuilder::Registrar install3D("3d", new TexBuilder<Texture3D>("3d"));
|
||||
class WhiteTextureBuilder : public TextureBuilder
|
||||
{
|
||||
public:
|
||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
||||
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||
const SGReaderWriterOptions* options);
|
||||
};
|
||||
|
||||
Texture* WhiteTextureBuilder::build(Effect* effect, const SGPropertyNode*,
|
||||
Texture* WhiteTextureBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||
const SGReaderWriterOptions* options)
|
||||
{
|
||||
return StateAttributeFactory::instance()->getWhiteTexture();
|
||||
@ -329,11 +329,11 @@ TextureBuilder::Registrar installWhite("white", new WhiteTextureBuilder);
|
||||
class TransparentTextureBuilder : public TextureBuilder
|
||||
{
|
||||
public:
|
||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
||||
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||
const SGReaderWriterOptions* options);
|
||||
};
|
||||
|
||||
Texture* TransparentTextureBuilder::build(Effect* effect, const SGPropertyNode*,
|
||||
Texture* TransparentTextureBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||
const SGReaderWriterOptions* options)
|
||||
{
|
||||
return StateAttributeFactory::instance()->getTransparentTexture();
|
||||
@ -393,14 +393,14 @@ osg::Image* make3DNoiseImage(int texSize)
|
||||
class NoiseBuilder : public TextureBuilder
|
||||
{
|
||||
public:
|
||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
||||
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||
const SGReaderWriterOptions* options);
|
||||
protected:
|
||||
typedef map<int, ref_ptr<Texture3D> > NoiseMap;
|
||||
NoiseMap _noises;
|
||||
};
|
||||
|
||||
Texture* NoiseBuilder::build(Effect* effect, const SGPropertyNode* props,
|
||||
Texture* NoiseBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* props,
|
||||
const SGReaderWriterOptions* options)
|
||||
{
|
||||
int texSize = 64;
|
||||
@ -461,7 +461,7 @@ CubeMapTuple makeCubeMapTuple(Effect* effect, const SGPropertyNode* props)
|
||||
class CubeMapBuilder : public TextureBuilder
|
||||
{
|
||||
public:
|
||||
Texture* build(Effect* effect, const SGPropertyNode*,
|
||||
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
|
||||
const SGReaderWriterOptions* options);
|
||||
protected:
|
||||
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)
|
||||
{
|
||||
// First check that there is a <images> tag
|
||||
@ -876,4 +876,45 @@ bool makeTextureParameters(SGPropertyNode* paramRoot, const StateSet* ss)
|
||||
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:
|
||||
// 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 SGReaderWriterOptions* options);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user