Merge branch 'zan/generate' into next
This commit is contained in:
commit
0ad66f4bc4
@ -98,6 +98,8 @@ Effect::Effect(const Effect& rhs, const CopyOp& copyop)
|
||||
itr != end;
|
||||
++itr)
|
||||
techniques.push_back(static_cast<Technique*>(copyop(itr->get())));
|
||||
|
||||
generator = rhs.generator;
|
||||
}
|
||||
|
||||
// Assume that the last technique is always valid.
|
||||
@ -110,6 +112,13 @@ StateSet* Effect::getDefaultStateSet()
|
||||
return pass;
|
||||
}
|
||||
|
||||
int Effect::getGenerator(Effect::Generator what) const
|
||||
{
|
||||
std::map<Generator,int>::const_iterator it = generator.find(what);
|
||||
if(it == generator.end()) return -1;
|
||||
else return it->second;
|
||||
}
|
||||
|
||||
// There should always be a valid technique in an effect.
|
||||
|
||||
Technique* Effect::chooseTechnique(RenderInfo* info)
|
||||
|
@ -80,6 +80,18 @@ public:
|
||||
Effect(const Effect& rhs,
|
||||
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
|
||||
osg::StateSet* getDefaultStateSet();
|
||||
|
||||
// Define what needs to be generated for this effect
|
||||
enum Generator
|
||||
{
|
||||
NORMAL,
|
||||
TANGENT,
|
||||
BINORMAL
|
||||
};
|
||||
void setGenerator(Generator what, int where) { generator[what] = where; }
|
||||
int getGenerator(Generator what) const; // Returns -1 if generator should not be used
|
||||
std::map<Generator, int> generator; // What is generated into which attribute location
|
||||
|
||||
std::vector<osg::ref_ptr<Technique> > techniques;
|
||||
SGPropertyNode_ptr root;
|
||||
// Pointer to the parameters node, if it exists
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "Technique.hxx"
|
||||
|
||||
#include <osgUtil/CullVisitor>
|
||||
#include <osgUtil/TangentSpaceGenerator>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/Input>
|
||||
@ -66,6 +67,31 @@ void EffectGeode::releaseGLObjects(osg::State* state) const
|
||||
Geode::releaseGLObjects(state);
|
||||
}
|
||||
|
||||
// Generates tangent space vectors or other data from geom, as defined by effect
|
||||
void EffectGeode::runGenerators(osg::Geometry *geometry)
|
||||
{
|
||||
if(geometry && _effect.valid()) {
|
||||
// Generate tangent vectors for the geometry
|
||||
osg::ref_ptr<osgUtil::TangentSpaceGenerator> tsg = new osgUtil::TangentSpaceGenerator;
|
||||
|
||||
// Generating only tangent vector should be enough
|
||||
// since the binormal is a cross product of normal and tangent
|
||||
// This saves a bit of memory & memory bandwidth!
|
||||
int n = _effect->getGenerator(Effect::TANGENT);
|
||||
tsg->generate(geometry, 0); // 0 is normal_unit, but I have no idea what that is!
|
||||
if (n != -1 && !geometry->getVertexAttribArray(n))
|
||||
geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getTangentArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
|
||||
|
||||
n = _effect->getGenerator(Effect::BINORMAL);
|
||||
if (n != -1 && !geometry->getVertexAttribArray(n))
|
||||
geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getBinormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
|
||||
|
||||
n = _effect->getGenerator(Effect::NORMAL);
|
||||
if (n != -1 && !geometry->getVertexAttribArray(n))
|
||||
geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getNormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
|
||||
}
|
||||
}
|
||||
|
||||
bool EffectGeode_writeLocalData(const Object& obj, osgDB::Output& fw)
|
||||
{
|
||||
const EffectGeode& eg = static_cast<const EffectGeode&>(obj);
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
typedef DrawableList::iterator DrawablesIterator;
|
||||
DrawablesIterator drawablesBegin() { return _drawables.begin(); }
|
||||
DrawablesIterator drawablesEnd() { return _drawables.end(); }
|
||||
void runGenerators(osg::Geometry *geometry);
|
||||
private:
|
||||
osg::ref_ptr<Effect> _effect;
|
||||
};
|
||||
|
@ -205,8 +205,10 @@ Effect* makeEffect(SGPropertyNode* prop,
|
||||
lock(effectMutex);
|
||||
cache = parent->getCache();
|
||||
itr = cache->find(key);
|
||||
if (itr != cache->end())
|
||||
if (itr != cache->end()) {
|
||||
effect = itr->second.get();
|
||||
effect->generator = parent->generator; // Copy the generators
|
||||
}
|
||||
}
|
||||
if (!effect.valid()) {
|
||||
effect = new Effect;
|
||||
@ -219,6 +221,7 @@ Effect* makeEffect(SGPropertyNode* prop,
|
||||
= cache->insert(make_pair(key, effect));
|
||||
if (!irslt.second)
|
||||
effect = irslt.first->second;
|
||||
effect->generator = parent->generator; // Copy the generators
|
||||
}
|
||||
} else {
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "can't find base effect " <<
|
||||
@ -230,6 +233,21 @@ Effect* makeEffect(SGPropertyNode* prop,
|
||||
effect->root = prop;
|
||||
effect->parametersProp = effect->root->getChild("parameters");
|
||||
}
|
||||
const SGPropertyNode *generateProp = prop->getChild("generate");
|
||||
if(generateProp)
|
||||
{
|
||||
effect->generator.clear();
|
||||
|
||||
// Effect needs some generated properties, like tangent vectors
|
||||
const SGPropertyNode *parameter = generateProp->getChild("normal");
|
||||
if(parameter) effect->setGenerator(Effect::NORMAL, parameter->getIntValue());
|
||||
|
||||
parameter = generateProp->getChild("tangent");
|
||||
if(parameter) effect->setGenerator(Effect::TANGENT, parameter->getIntValue());
|
||||
|
||||
parameter = generateProp->getChild("binormal");
|
||||
if(parameter) effect->setGenerator(Effect::BINORMAL, parameter->getIntValue());
|
||||
}
|
||||
if (realizeTechniques) {
|
||||
try {
|
||||
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex>
|
||||
|
@ -274,8 +274,14 @@ void MakeEffectVisitor::apply(osg::Geode& geode)
|
||||
ref_ptr<SGSceneUserData> userData = SGSceneUserData::getSceneUserData(&geode);
|
||||
if (userData.valid())
|
||||
eg->setUserData(new SGSceneUserData(*userData));
|
||||
for (int i = 0; i < geode.getNumDrawables(); ++i)
|
||||
eg->addDrawable(geode.getDrawable(i));
|
||||
for (int i = 0; i < geode.getNumDrawables(); ++i) {
|
||||
osg::Drawable *drawable = geode.getDrawable(i);
|
||||
eg->addDrawable(drawable);
|
||||
|
||||
// Generate tangent vectors etc if needed
|
||||
osg::Geometry *geom = dynamic_cast<osg::Geometry*>(drawable);
|
||||
if(geom) eg->runGenerators(geom);
|
||||
}
|
||||
}
|
||||
pushResultNode(&geode, eg);
|
||||
|
||||
|
@ -310,6 +310,7 @@ osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
|
||||
geode->setName("Ocean tile");
|
||||
geode->setEffect(effect);
|
||||
geode->addDrawable(geometry);
|
||||
geode->runGenerators(geometry);
|
||||
|
||||
osg::MatrixTransform* transform = new osg::MatrixTransform;
|
||||
transform->setName("Ocean");
|
||||
|
@ -382,6 +382,7 @@ struct SGTileGeometryBin {
|
||||
if (mat)
|
||||
eg->setEffect(mat->get_effect());
|
||||
eg->addDrawable(geometry);
|
||||
eg->runGenerators(geometry); // Generate extra data needed by effect
|
||||
if (group)
|
||||
group->addChild(eg);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user