1 // Copyright (C) 2008 Timothy Moore timoore@redhat.com
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License as
5 // published by the Free Software Foundation; either version 2 of the
6 // License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful, but
9 // WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # include <simgear_config.h>
21 #include "EffectGeode.hxx"
23 #include "Technique.hxx"
25 #include <osg/Version>
27 #include <osgUtil/CullVisitor>
28 #include <osgUtil/TangentSpaceGenerator>
30 #include <osgDB/Registry>
31 #include <osgDB/Input>
32 #include <osgDB/ParameterOutput>
38 using namespace osgUtil;
40 EffectGeode::EffectGeode()
44 EffectGeode::EffectGeode(const EffectGeode& rhs, const osg::CopyOp& copyop) :
46 _effect(static_cast<Effect*>(copyop(rhs._effect.get())))
50 void EffectGeode::setEffect(Effect* effect)
55 //TODO: do we leak the callbacks or does the geode own pointer afterwards?
56 addUpdateCallback(new Effect::InitializeCallback);
57 addUpdateCallback(new Effect::UpdateCallback);
60 void EffectGeode::resizeGLObjectBuffers(unsigned int maxSize)
63 _effect->resizeGLObjectBuffers(maxSize);
64 Geode::resizeGLObjectBuffers(maxSize);
67 void EffectGeode::releaseGLObjects(osg::State* state) const
70 _effect->releaseGLObjects(state);
71 Geode::releaseGLObjects(state);
74 // Generates tangent space vectors or other data from geom, as defined by effect
75 void EffectGeode::runGenerators(osg::Geometry *geometry)
77 if(geometry && _effect.valid()) {
78 // Generate tangent vectors for the geometry
79 osg::ref_ptr<osgUtil::TangentSpaceGenerator> tsg = new osgUtil::TangentSpaceGenerator;
81 // Generating only tangent vector should be enough
82 // since the binormal is a cross product of normal and tangent
83 // This saves a bit of memory & memory bandwidth!
84 int n = _effect->getGenerator(Effect::TANGENT);
85 tsg->generate(geometry, 0); // 0 is normal_unit, but I have no idea what that is!
86 if (n != -1 && !geometry->getVertexAttribArray(n))
87 #if OSG_MIN_VERSION_REQUIRED(3,1,8)
88 geometry->setVertexAttribArray(n, tsg->getTangentArray(), osg::Array::BIND_PER_VERTEX);
90 geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getTangentArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
93 n = _effect->getGenerator(Effect::BINORMAL);
94 if (n != -1 && !geometry->getVertexAttribArray(n))
95 #if OSG_MIN_VERSION_REQUIRED(3,1,8)
96 geometry->setVertexAttribArray(n, tsg->getBinormalArray(), osg::Array::BIND_PER_VERTEX);
98 geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getBinormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
101 n = _effect->getGenerator(Effect::NORMAL);
102 if (n != -1 && !geometry->getVertexAttribArray(n))
103 #if OSG_MIN_VERSION_REQUIRED(3,1,8)
104 geometry->setVertexAttribArray(n, tsg->getNormalArray(), osg::Array::BIND_PER_VERTEX);
106 geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getNormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
111 bool EffectGeode_writeLocalData(const Object& obj, osgDB::Output& fw)
113 const EffectGeode& eg = static_cast<const EffectGeode&>(obj);
115 if (eg.getEffect()) {
116 fw.indent() << "effect\n";
117 fw.writeObject(*eg.getEffect());
125 osgDB::RegisterDotOsgWrapperProxy effectGeodeProxy
128 "simgear::EffectGeode",
129 "Object Node Geode simgear::EffectGeode",
131 &EffectGeode_writeLocalData