Merge branch 'zan/generate'
This commit is contained in:
commit
3d91a11b95
@ -98,6 +98,8 @@ Effect::Effect(const Effect& rhs, const CopyOp& copyop)
|
|||||||
itr != end;
|
itr != end;
|
||||||
++itr)
|
++itr)
|
||||||
techniques.push_back(static_cast<Technique*>(copyop(itr->get())));
|
techniques.push_back(static_cast<Technique*>(copyop(itr->get())));
|
||||||
|
|
||||||
|
generator = rhs.generator;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume that the last technique is always valid.
|
// Assume that the last technique is always valid.
|
||||||
@ -110,6 +112,13 @@ StateSet* Effect::getDefaultStateSet()
|
|||||||
return pass;
|
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.
|
// There should always be a valid technique in an effect.
|
||||||
|
|
||||||
Technique* Effect::chooseTechnique(RenderInfo* info)
|
Technique* Effect::chooseTechnique(RenderInfo* info)
|
||||||
|
@ -80,6 +80,18 @@ public:
|
|||||||
Effect(const Effect& rhs,
|
Effect(const Effect& rhs,
|
||||||
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
|
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
|
||||||
osg::StateSet* getDefaultStateSet();
|
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;
|
std::vector<osg::ref_ptr<Technique> > techniques;
|
||||||
SGPropertyNode_ptr root;
|
SGPropertyNode_ptr root;
|
||||||
// Pointer to the parameters node, if it exists
|
// Pointer to the parameters node, if it exists
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "Technique.hxx"
|
#include "Technique.hxx"
|
||||||
|
|
||||||
#include <osgUtil/CullVisitor>
|
#include <osgUtil/CullVisitor>
|
||||||
|
#include <osgUtil/TangentSpaceGenerator>
|
||||||
|
|
||||||
#include <osgDB/Registry>
|
#include <osgDB/Registry>
|
||||||
#include <osgDB/Input>
|
#include <osgDB/Input>
|
||||||
@ -66,6 +67,31 @@ void EffectGeode::releaseGLObjects(osg::State* state) const
|
|||||||
Geode::releaseGLObjects(state);
|
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)
|
bool EffectGeode_writeLocalData(const Object& obj, osgDB::Output& fw)
|
||||||
{
|
{
|
||||||
const EffectGeode& eg = static_cast<const EffectGeode&>(obj);
|
const EffectGeode& eg = static_cast<const EffectGeode&>(obj);
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
typedef DrawableList::iterator DrawablesIterator;
|
typedef DrawableList::iterator DrawablesIterator;
|
||||||
DrawablesIterator drawablesBegin() { return _drawables.begin(); }
|
DrawablesIterator drawablesBegin() { return _drawables.begin(); }
|
||||||
DrawablesIterator drawablesEnd() { return _drawables.end(); }
|
DrawablesIterator drawablesEnd() { return _drawables.end(); }
|
||||||
|
void runGenerators(osg::Geometry *geometry);
|
||||||
private:
|
private:
|
||||||
osg::ref_ptr<Effect> _effect;
|
osg::ref_ptr<Effect> _effect;
|
||||||
};
|
};
|
||||||
|
@ -205,8 +205,10 @@ Effect* makeEffect(SGPropertyNode* prop,
|
|||||||
lock(effectMutex);
|
lock(effectMutex);
|
||||||
cache = parent->getCache();
|
cache = parent->getCache();
|
||||||
itr = cache->find(key);
|
itr = cache->find(key);
|
||||||
if (itr != cache->end())
|
if (itr != cache->end()) {
|
||||||
effect = itr->second.get();
|
effect = itr->second.get();
|
||||||
|
effect->generator = parent->generator; // Copy the generators
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!effect.valid()) {
|
if (!effect.valid()) {
|
||||||
effect = new Effect;
|
effect = new Effect;
|
||||||
@ -219,6 +221,7 @@ Effect* makeEffect(SGPropertyNode* prop,
|
|||||||
= cache->insert(make_pair(key, effect));
|
= cache->insert(make_pair(key, effect));
|
||||||
if (!irslt.second)
|
if (!irslt.second)
|
||||||
effect = irslt.first->second;
|
effect = irslt.first->second;
|
||||||
|
effect->generator = parent->generator; // Copy the generators
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_INPUT, SG_ALERT, "can't find base effect " <<
|
SG_LOG(SG_INPUT, SG_ALERT, "can't find base effect " <<
|
||||||
@ -230,6 +233,21 @@ Effect* makeEffect(SGPropertyNode* prop,
|
|||||||
effect->root = prop;
|
effect->root = prop;
|
||||||
effect->parametersProp = effect->root->getChild("parameters");
|
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) {
|
if (realizeTechniques) {
|
||||||
try {
|
try {
|
||||||
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex>
|
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex>
|
||||||
|
@ -274,8 +274,14 @@ void MakeEffectVisitor::apply(osg::Geode& geode)
|
|||||||
ref_ptr<SGSceneUserData> userData = SGSceneUserData::getSceneUserData(&geode);
|
ref_ptr<SGSceneUserData> userData = SGSceneUserData::getSceneUserData(&geode);
|
||||||
if (userData.valid())
|
if (userData.valid())
|
||||||
eg->setUserData(new SGSceneUserData(*userData));
|
eg->setUserData(new SGSceneUserData(*userData));
|
||||||
for (int i = 0; i < geode.getNumDrawables(); ++i)
|
for (int i = 0; i < geode.getNumDrawables(); ++i) {
|
||||||
eg->addDrawable(geode.getDrawable(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);
|
pushResultNode(&geode, eg);
|
||||||
|
|
||||||
|
@ -310,6 +310,7 @@ osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
|
|||||||
geode->setName("Ocean tile");
|
geode->setName("Ocean tile");
|
||||||
geode->setEffect(effect);
|
geode->setEffect(effect);
|
||||||
geode->addDrawable(geometry);
|
geode->addDrawable(geometry);
|
||||||
|
geode->runGenerators(geometry);
|
||||||
|
|
||||||
osg::MatrixTransform* transform = new osg::MatrixTransform;
|
osg::MatrixTransform* transform = new osg::MatrixTransform;
|
||||||
transform->setName("Ocean");
|
transform->setName("Ocean");
|
||||||
|
@ -382,6 +382,7 @@ struct SGTileGeometryBin {
|
|||||||
if (mat)
|
if (mat)
|
||||||
eg->setEffect(mat->get_effect());
|
eg->setEffect(mat->get_effect());
|
||||||
eg->addDrawable(geometry);
|
eg->addDrawable(geometry);
|
||||||
|
eg->runGenerators(geometry); // Generate extra data needed by effect
|
||||||
if (group)
|
if (group)
|
||||||
group->addChild(eg);
|
group->addChild(eg);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user