#include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/structure/OSGUtils.hxx>
+#include <simgear/props/vectorPropTemplates.hxx>
namespace simgear
{
texType, mipmapFunctions);
}
-void setAttrs(const TexTuple& attrs, Texture* tex,
+bool setAttrs(const TexTuple& attrs, Texture* tex,
const SGReaderWriterOptions* options)
{
const string& imageName = attrs.get<0>();
- if (imageName.empty()) {
- throw BuilderException("no image file");
- } else {
- osgDB::ReaderWriter::ReadResult result;
- result = osgDB::readImageFile(imageName, options);
- osg::ref_ptr<osg::Image> image;
- if (result.success())
- image = result.getImage();
- if (image.valid())
- {
- image = computeMipmap( image.get(), attrs.get<7>() );
- tex->setImage(GL_FRONT_AND_BACK, image.get());
- int s = image->s();
- int t = image->t();
- if (s <= t && 32 <= s) {
- SGSceneFeatures::instance()->setTextureCompression(tex);
- } else if (t < s && 32 <= t) {
- SGSceneFeatures::instance()->setTextureCompression(tex);
- }
- tex->setMaxAnisotropy(SGSceneFeatures::instance()
- ->getTextureFilter());
- } else {
- SG_LOG(SG_INPUT, SG_ALERT, "failed to load effect texture file "
- << imageName);
+ if (imageName.empty())
+ return false;
+
+ osgDB::ReaderWriter::ReadResult result;
+ result = osgDB::readImageFile(imageName, options);
+ osg::ref_ptr<osg::Image> image;
+ if (result.success())
+ image = result.getImage();
+ if (image.valid())
+ {
+ image = computeMipmap( image.get(), attrs.get<7>() );
+ tex->setImage(GL_FRONT_AND_BACK, image.get());
+ int s = image->s();
+ int t = image->t();
+ if (s <= t && 32 <= s) {
+ SGSceneFeatures::instance()->setTextureCompression(tex);
+ } else if (t < s && 32 <= t) {
+ SGSceneFeatures::instance()->setTextureCompression(tex);
}
+ tex->setMaxAnisotropy(SGSceneFeatures::instance()
+ ->getTextureFilter());
+ } else {
+ SG_LOG(SG_INPUT, SG_ALERT, "failed to load effect texture file "
+ << imageName);
+ return false;
}
+
// texture->setDataVariance(osg::Object::STATIC);
tex->setFilter(Texture::MIN_FILTER, attrs.get<1>());
tex->setFilter(Texture::MAG_FILTER, attrs.get<2>());
tex->setWrap(Texture::WRAP_S, attrs.get<3>());
tex->setWrap(Texture::WRAP_T, attrs.get<4>());
tex->setWrap(Texture::WRAP_R, attrs.get<5>());
+ return true;
}
-}
+
+} // of anonymous namespace
template<typename T>
class TexBuilder : public TextureBuilder
}
tex = new T;
- setAttrs(attrs, tex, options);
+ if (!setAttrs(attrs, tex, options))
+ return NULL;
+
if (itr == texMap.end())
texMap.insert(make_pair(attrs, tex));
else
class GBufferBuilder : public TextureBuilder
{
public:
- GBufferBuilder(int b) : buffer(b) {}
+ GBufferBuilder() {}
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
const SGReaderWriterOptions* options);
private:
- int buffer;
+ string buffer;
+};
+
+class BufferNameChangeListener : public SGPropertyChangeListener, public InitializeWhenAdded,
+ public Effect::Updater {
+public:
+ BufferNameChangeListener(Pass* p, int u, const std::string& pn) : pass(p), unit(u)
+ {
+ propName = new std::string(pn);
+ }
+ ~BufferNameChangeListener()
+ {
+ delete propName;
+ propName = 0;
+ }
+ void valueChanged(SGPropertyNode* node)
+ {
+ const char* buffer = node->getStringValue();
+ pass->setBufferUnit(unit, buffer);
+ }
+ void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
+ {
+ SGPropertyNode* listenProp = makeNode(propRoot, *propName);
+ delete propName;
+ propName = 0;
+ if (listenProp)
+ listenProp->addChangeListener(this, true);
+ }
+
+private:
+ ref_ptr<Pass> pass;
+ int unit;
+ std::string* propName;
};
Texture* GBufferBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* prop,
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());
- }
+ SG_LOG(SG_INPUT, SG_ALERT, "no texture unit");
+ }
+ const SGPropertyNode* nameProp = getEffectPropertyChild(effect, prop,
+ "name");
+ if (!nameProp)
+ return 0;
+
+ if (nameProp->nChildren() == 0) {
+ buffer = nameProp->getStringValue();
+ pass->setBufferUnit( unit, buffer );
+ } else {
+ std::string propName = getGlobalProperty(nameProp, options);
+ BufferNameChangeListener* listener = new BufferNameChangeListener(pass, unit, propName);
+ effect->addUpdater(listener);
}
- 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(Effect::DEPTH_BUFFER));
- TextureBuilder::Registrar installNormalBuffer("normal-buffer", new GBufferBuilder(Effect::NORMAL_BUFFER));
- TextureBuilder::Registrar installDiffuseBuffer("diffuse-buffer", new GBufferBuilder(Effect::DIFFUSE_BUFFER));
- TextureBuilder::Registrar installSpecularBuffer("spec-emis-buffer", new GBufferBuilder(Effect::SPEC_EMIS_BUFFER));
- TextureBuilder::Registrar installLightingBuffer("lighting-buffer", new GBufferBuilder(Effect::LIGHTING_BUFFER));
- TextureBuilder::Registrar installMiddleBloomBuffer("middle-bloom-buffer", new GBufferBuilder(Effect::MIDDLE_BLOOM_BUFFER));
- TextureBuilder::Registrar installBloomBuffer("bloom-buffer", new GBufferBuilder(Effect::BLOOM_BUFFER));
- TextureBuilder::Registrar installAoBuffer("ao-buffer", new GBufferBuilder(Effect::AO_BUFFER));
- TextureBuilder::Registrar installShadowBuffer("shadow-buffer", new GBufferBuilder(Effect::SHADOW_BUFFER));
+ TextureBuilder::Registrar installBuffer("buffer", new GBufferBuilder);
}
}