#include "Technique.hxx"
#include "Pass.hxx"
+#include "EffectCullVisitor.hxx"
#include <boost/foreach.hpp>
#include <osg/GLExtensions>
#include <osg/GL2Extensions>
#include <osg/Math>
+#include <osg/Texture2D>
+#include <osg/CopyOp>
#include <osgUtil/CullVisitor>
#include <osgDB/Registry>
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)
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,
type = pType->getStringValue();
Texture* texture = 0;
try {
- texture = TextureBuilder::buildFromType(effect, type, prop,
+ texture = TextureBuilder::buildFromType(effect, pass, type, prop,
options);
}
catch (BuilderException& e) {
{
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;
};
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);
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();
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();
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;
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;
}
-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
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));
+}
+
}