From c6b2124129e908d95ccfdf9d11a51cd257e55e55 Mon Sep 17 00:00:00 2001 From: timoore Date: Wed, 15 Jul 2009 23:09:31 +0000 Subject: [PATCH] Use Effects in materials library, and therefore in scenery --- simgear/scene/material/Effect.cxx | 50 +++++++++++++++- simgear/scene/material/Effect.hxx | 4 +- simgear/scene/material/EffectCullVisitor.cxx | 63 ++++++++++++++++++++ simgear/scene/material/EffectCullVisitor.hxx | 39 ++++++++++++ simgear/scene/material/EffectGeode.cxx | 47 ++++++++++----- simgear/scene/material/EffectGeode.hxx | 5 +- simgear/scene/material/Makefile.am | 2 + simgear/scene/material/Pass.cxx | 23 +++++++ simgear/scene/material/Pass.hxx | 1 + simgear/scene/material/Technique.cxx | 44 +++++++++++++- simgear/scene/material/Technique.hxx | 11 +++- simgear/scene/material/mat.cxx | 41 ++++++++++++- simgear/scene/material/mat.hxx | 48 ++++++++------- simgear/scene/material/matlib.cxx | 2 + simgear/scene/sky/cloud.cxx | 7 ++- simgear/scene/tgdb/obj.cxx | 18 ++++-- 16 files changed, 348 insertions(+), 57 deletions(-) create mode 100644 simgear/scene/material/EffectCullVisitor.cxx create mode 100644 simgear/scene/material/EffectCullVisitor.hxx diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index 646a0096..9625fb3b 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -1,5 +1,6 @@ #include "Effect.hxx" #include "Technique.hxx" +#include "Pass.hxx" #include #include @@ -11,8 +12,10 @@ #include #include #include - #include +#include +#include +#include #include @@ -23,6 +26,10 @@ namespace simgear using namespace osg; using namespace osgUtil; +Effect::Effect() +{ +} + Effect::Effect(const Effect& rhs, const CopyOp& copyop) { using namespace std; @@ -31,6 +38,19 @@ Effect::Effect(const Effect& rhs, const CopyOp& copyop) backRefInsertIterator(techniques), bind(simgear::clone_ref, _1, copyop)); } + +// Assume that the last technique is always valid. +StateSet* Effect::getDefaultStateSet() +{ + Technique* tniq = techniques.back().get(); + if (!tniq) + return 0; + Pass* pass = tniq->passes.front().get(); + if (!pass) + return 0; + return pass->getStateSet(); +} + // There should always be a valid technique in an effect. Technique* Effect::chooseTechnique(RenderInfo* info) @@ -58,4 +78,32 @@ void Effect::releaseGLObjects(osg::State* state) const technique->releaseGLObjects(state); } } + +Effect::~Effect() +{ +} + +bool Effect_writeLocalData(const Object& obj, osgDB::Output& fw) +{ + const Effect& effect = static_cast(obj); + + fw.indent() << "techniques " << effect.techniques.size() << "\n"; + BOOST_FOREACH(const ref_ptr& technique, effect.techniques) { + fw.writeObject(*technique); + } + return true; +} + +namespace +{ +osgDB::RegisterDotOsgWrapperProxy effectProxy +( + new Effect, + "simgear::Effect", + "Object simgear::Effect", + 0, + &Effect_writeLocalData + ); } +} + diff --git a/simgear/scene/material/Effect.hxx b/simgear/scene/material/Effect.hxx index c6752343..8c86d945 100644 --- a/simgear/scene/material/Effect.hxx +++ b/simgear/scene/material/Effect.hxx @@ -42,7 +42,7 @@ class Effect : public osg::Object { public: META_Object(simgear,Effect) - Effect() {} + Effect(); Effect(const Effect& rhs, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); osg::StateSet* getDefaultStateSet(); @@ -51,7 +51,7 @@ public: virtual void resizeGLObjectBuffers(unsigned int maxSize); virtual void releaseGLObjects(osg::State* state = 0) const; protected: - ~Effect() {} + ~Effect(); }; } #endif diff --git a/simgear/scene/material/EffectCullVisitor.cxx b/simgear/scene/material/EffectCullVisitor.cxx new file mode 100644 index 00000000..8d86d8e0 --- /dev/null +++ b/simgear/scene/material/EffectCullVisitor.cxx @@ -0,0 +1,63 @@ +// Copyright (C) 2008 Timothy Moore timoore@redhat.com +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +#include "EffectCullVisitor.hxx" + +#include "EffectGeode.hxx" +#include "Effect.hxx" +#include "Technique.hxx" + +namespace simgear +{ + +using osgUtil::CullVisitor; + +EffectCullVisitor::EffectCullVisitor() +{ +} + +EffectCullVisitor::EffectCullVisitor(const EffectCullVisitor& rhs) : + CullVisitor(rhs) +{ +} + +CullVisitor* EffectCullVisitor::clone() const +{ + return new EffectCullVisitor(*this); +} + +void EffectCullVisitor::apply(osg::Geode& node) +{ + if (isCulled(node)) + return; + EffectGeode *eg = dynamic_cast(&node); + if (!eg) { + CullVisitor::apply(node); + return; + } + Technique* technique = eg->getEffect()->chooseTechnique(&getRenderInfo()); + if (!technique) { + CullVisitor::apply(node); + return; + } + for (EffectGeode::DrawablesIterator beginItr = eg->drawablesBegin(), + e = eg->drawablesEnd(); + beginItr != e; + beginItr = technique->processDrawables(beginItr, e, this, + eg->isCullingActive())) + ; +} +} diff --git a/simgear/scene/material/EffectCullVisitor.hxx b/simgear/scene/material/EffectCullVisitor.hxx new file mode 100644 index 00000000..fa752c8f --- /dev/null +++ b/simgear/scene/material/EffectCullVisitor.hxx @@ -0,0 +1,39 @@ +// Copyright (C) 2008 Timothy Moore timoore@redhat.com +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +#ifndef SIMGEAR_EFFECT_CULL_VISITOR_HXX +#define SIMGEAR_EFFECT_CULL_VISITOR_HXX 1 + +#include + +namespace osg +{ +class Geode; +} + +namespace simgear +{ +class EffectCullVisitor : public osgUtil::CullVisitor +{ +public: + EffectCullVisitor(); + EffectCullVisitor(const EffectCullVisitor&); + virtual osgUtil::CullVisitor* clone() const; + using osgUtil::CullVisitor::apply; + virtual void apply(osg::Geode& node); +}; +} +#endif diff --git a/simgear/scene/material/EffectGeode.cxx b/simgear/scene/material/EffectGeode.cxx index 62a56d32..78b17ac0 100644 --- a/simgear/scene/material/EffectGeode.cxx +++ b/simgear/scene/material/EffectGeode.cxx @@ -20,29 +20,24 @@ #include +#include +#include +#include + namespace simgear { using namespace osg; using namespace osgUtil; -void EffectGeode::traverse(NodeVisitor& nv) +EffectGeode::EffectGeode() { - CullVisitor* cv = dynamic_cast(&nv); - if (!cv || !_effect.valid()) { - Geode::traverse(nv); - return; - } - Technique* technique = _effect->chooseTechnique(&cv->getRenderInfo()); - if (!technique) { - Geode::traverse(nv); - return; - } - for (DrawablesIterator beginItr = _drawables.begin(); - beginItr != _drawables.end(); - beginItr = technique->processDrawables(beginItr, _drawables.end(), cv, - isCullingActive())) - ; +} + +EffectGeode::EffectGeode(const EffectGeode& rhs, const CopyOp& copyop) : + Geode(rhs, copyop) +{ + _effect = static_cast(rhs._effect->clone(copyop)); } void EffectGeode::resizeGLObjectBuffers(unsigned int maxSize) @@ -59,4 +54,24 @@ void EffectGeode::releaseGLObjects(osg::State* state) const Geode::releaseGLObjects(state); } +bool EffectGeode_writeLocalData(const Object& obj, osgDB::Output& fw) +{ + const EffectGeode& eg = static_cast(obj); + + fw.indent() << "effect\n"; + fw.writeObject(*eg.getEffect()); + return true; +} + +namespace +{ +osgDB::RegisterDotOsgWrapperProxy effectGeodeProxy +( + new EffectGeode, + "simgear::EffectGeode", + "Object Node Geode simgear::EffectGeode", + 0, + &EffectGeode_writeLocalData + ); +} } diff --git a/simgear/scene/material/EffectGeode.hxx b/simgear/scene/material/EffectGeode.hxx index 209a4a1c..ad35beb9 100644 --- a/simgear/scene/material/EffectGeode.hxx +++ b/simgear/scene/material/EffectGeode.hxx @@ -30,12 +30,13 @@ public: EffectGeode(const EffectGeode& rhs, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); META_Node(simgear,EffectGeode); - virtual void traverse(osg::NodeVisitor& nv); Effect* getEffect() const { return _effect.get(); } - void setEffect(Effect* effect); + void setEffect(Effect* effect) { _effect = effect; } virtual void resizeGLObjectBuffers(unsigned int maxSize); virtual void releaseGLObjects(osg::State* = 0) const; typedef DrawableList::iterator DrawablesIterator; + DrawablesIterator drawablesBegin() { return _drawables.begin(); } + DrawablesIterator drawablesEnd() { return _drawables.end(); } private: osg::ref_ptr _effect; }; diff --git a/simgear/scene/material/Makefile.am b/simgear/scene/material/Makefile.am index c81bdbcc..95cab757 100644 --- a/simgear/scene/material/Makefile.am +++ b/simgear/scene/material/Makefile.am @@ -6,6 +6,7 @@ noinst_HEADERS = include_HEADERS = \ Effect.hxx \ + EffectCullVisitor.hxx \ EffectGeode.hxx \ Pass.hxx \ Technique.hxx \ @@ -15,6 +16,7 @@ include_HEADERS = \ libsgmaterial_a_SOURCES = \ Effect.cxx \ + EffectCullVisitor.cxx \ EffectGeode.cxx \ Pass.cxx \ Technique.cxx \ diff --git a/simgear/scene/material/Pass.cxx b/simgear/scene/material/Pass.cxx index dc882d4c..210a8506 100644 --- a/simgear/scene/material/Pass.cxx +++ b/simgear/scene/material/Pass.cxx @@ -3,6 +3,9 @@ #include #include +#include +#include +#include namespace simgear { @@ -24,4 +27,24 @@ void Pass::releaseGLObjects(osg::State* state) const _stateSet->releaseGLObjects(state); } +bool Pass_writeLocalData(const osg::Object& obj, osgDB::Output& fw) +{ + const Pass& pass = static_cast(obj); + + fw.indent() << "stateSet\n"; + fw.writeObject(*pass.getStateSet()); + return true; +} + +namespace +{ +osgDB::RegisterDotOsgWrapperProxy passProxy +( + new Pass, + "simgear::Pass", + "Object simgear::Pass", + 0, + &Pass_writeLocalData + ); +} } diff --git a/simgear/scene/material/Pass.hxx b/simgear/scene/material/Pass.hxx index e6b3dc90..cb343fcc 100644 --- a/simgear/scene/material/Pass.hxx +++ b/simgear/scene/material/Pass.hxx @@ -36,6 +36,7 @@ public: Pass(const Pass& rhs, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); osg::StateSet* getStateSet() { return _stateSet.get(); } + const osg::StateSet* getStateSet() const { return _stateSet.get(); } void setStateSet(osg::StateSet* stateSet) { _stateSet = stateSet; } virtual void resizeGLObjectBuffers(unsigned int maxSize); virtual void releaseGLObjects(osg::State* state = 0) const; diff --git a/simgear/scene/material/Technique.cxx b/simgear/scene/material/Technique.cxx index 38b463b4..d800f0cc 100644 --- a/simgear/scene/material/Technique.cxx +++ b/simgear/scene/material/Technique.cxx @@ -10,6 +10,10 @@ #include #include +#include +#include +#include + #include namespace simgear @@ -40,13 +44,14 @@ void ValidateOperation::operator() (GraphicsContext* gc) } } -Technique::Technique() : _glVersion(1.1f) +Technique::Technique(bool alwaysValid) + : _alwaysValid(alwaysValid), _glVersion(1.1f) { } Technique::Technique(const Technique& rhs, const osg::CopyOp& copyop) : - _contextMap(rhs._contextMap), _shadowingStateSet(rhs._shadowingStateSet), - _glVersion(rhs._glVersion) + _contextMap(rhs._contextMap), _alwaysValid(rhs._alwaysValid), + _shadowingStateSet(rhs._shadowingStateSet), _glVersion(rhs._glVersion) { using namespace std; using namespace boost; @@ -62,6 +67,8 @@ Technique::~Technique() Technique::Status Technique::valid(osg::RenderInfo* renderInfo) { + if (_alwaysValid) + return VALID; unsigned contextID = renderInfo->getContextID(); ContextInfo& contextInfo = _contextMap[contextID]; Status status = contextInfo.valid(); @@ -81,6 +88,8 @@ Technique::Status Technique::valid(osg::RenderInfo* renderInfo) Technique::Status Technique::getValidStatus(const RenderInfo* renderInfo) const { + if (_alwaysValid) + return VALID; ContextInfo& contextInfo = _contextMap[renderInfo->getContextID()]; return contextInfo.valid(); } @@ -177,4 +186,33 @@ void Technique::releaseGLObjects(osg::State* state) const info.valid.compareAndSwap(oldVal, UNKNOWN); } } + +bool Technique_writeLocalData(const Object& obj, osgDB::Output& fw) +{ + const Technique& tniq = static_cast(obj); + fw.indent() << "alwaysValid " + << (tniq.getAlwaysValid() ? "TRUE\n" : "FALSE\n"); + fw.indent() << "glVersion " << tniq.getGLVersion() << "\n"; + if (tniq.getShadowingStateSet()) { + fw.indent() << "shadowingStateSet\n"; + fw.writeObject(*tniq.getShadowingStateSet()); + } + fw.indent() << "passes\n"; + BOOST_FOREACH(const ref_ptr& pass, tniq.passes) { + fw.writeObject(*pass); + } + return true; +} + +namespace +{ +osgDB::RegisterDotOsgWrapperProxy TechniqueProxy +( + new Technique, + "simgear::Technique", + "Object simgear::Technique", + 0, + &Technique_writeLocalData + ); +} } diff --git a/simgear/scene/material/Technique.hxx b/simgear/scene/material/Technique.hxx index 8b18aeac..455ee35d 100644 --- a/simgear/scene/material/Technique.hxx +++ b/simgear/scene/material/Technique.hxx @@ -52,7 +52,7 @@ class Technique : public osg::Object { public: META_Object(simgear,Technique); - Technique(); + Technique(bool alwaysValid = false); Technique(const Technique& rhs, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); virtual ~Technique(); @@ -83,14 +83,20 @@ public: bool isCullingActive); std::vector > passes; osg::StateSet* getShadowingStateSet() { return _shadowingStateSet.get(); } + const osg::StateSet* getShadowingStateSet() const + { + return _shadowingStateSet.get(); + } void setShadowingStateSet(osg::StateSet* ss) { _shadowingStateSet = ss; } virtual void resizeGLObjectBuffers(unsigned int maxSize); virtual void releaseGLObjects(osg::State* state = 0) const; // Initial validity testing. Either the minimum OpenGL version // must be supported, or the list of extensions must be supported. - float getGLVersion() { return _glVersion; } + float getGLVersion() const { return _glVersion; } void setGLVersion(float glVersion) { _glVersion = glVersion; } std::vector glExtensions; + bool getAlwaysValid() const { return _alwaysValid; } + void setAlwaysValid(bool val) { _alwaysValid = val; } protected: // Validity of technique in a graphics context. struct ContextInfo : public osg::Referenced @@ -105,6 +111,7 @@ protected: }; typedef osg::buffered_object ContextMap; mutable ContextMap _contextMap; + bool _alwaysValid; osg::ref_ptr _shadowingStateSet; float _glVersion; }; diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index 4eda1dde..8230107a 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -30,9 +30,12 @@ #include #include +#include "mat.hxx" + #include #include #include +#include #include #include #include @@ -45,7 +48,9 @@ #include #include -#include "mat.hxx" +#include "Effect.hxx" +#include "Technique.hxx" +#include "Pass.hxx" using std::map; using namespace simgear; @@ -55,6 +60,11 @@ using namespace simgear; // Constructors and destructor. //////////////////////////////////////////////////////////////////////// +SGMaterial::_internal_state::_internal_state(osg::StateSet *s, + const std::string &t, bool l ) : + state(s), texture_path(t), texture_loaded(l) +{ +} SGMaterial::SGMaterial( const string &fg_root, const SGPropertyNode *props ) { @@ -244,15 +254,34 @@ SGMaterial::get_state (int n) return st; } +Effect* SGMaterial::get_effect(int n) +{ + if (_status.size() == 0) { + SG_LOG( SG_GENERAL, SG_WARN, "No effect available."); + return 0; + } + int i = n >= 0 ? n : _current_ptr; + if(!_status[i].texture_loaded) { + assignTexture(_status[i].state.get(), _status[i].texture_path, + wrapu, wrapv, mipmap); + _status[i].texture_loaded = true; + } + // XXX This business of returning a "random" alternate texture is + // really bogus. It means that the appearance of the terrain + // depends on the order in which it is paged in! + _current_ptr = (_current_ptr + 1) % _status.size(); + return _status[i].effect.get(); +} void SGMaterial::build_state( bool defer_tex_load ) { StateAttributeFactory *attrFact = StateAttributeFactory::instance(); + SGMaterialUserData* user = new SGMaterialUserData(this); for (unsigned int i = 0; i < _status.size(); i++) { osg::StateSet *stateSet = new osg::StateSet; - stateSet->setUserData(new SGMaterialUserData(this)); + stateSet->setUserData(user); // Set up the textured state stateSet->setAttribute(attrFact->getSmoothShadeModel()); @@ -283,6 +312,14 @@ SGMaterial::build_state( bool defer_tex_load ) } _status[i].state = stateSet; + Pass* pass = new Pass; + pass->setStateSet(_status[i].state.get()); + Technique* tniq = new Technique(true); + tniq->passes.push_back(pass); + Effect* effect = new Effect; + effect->techniques.push_back(tniq); + effect->setUserData(user); + _status[i].effect = effect; } } diff --git a/simgear/scene/material/mat.hxx b/simgear/scene/material/mat.hxx index 7b74d1ac..faccaf6b 100644 --- a/simgear/scene/material/mat.hxx +++ b/simgear/scene/material/mat.hxx @@ -39,7 +39,11 @@ #include #include -#include + +namespace osg +{ +class StateSet; +} #include #include @@ -47,10 +51,10 @@ #include "matmodel.hxx" -using std::string; -using std::vector; -using std::map; - +namespace simgear +{ +class Effect; +} class SGMaterialGlyph; @@ -79,7 +83,7 @@ public: * state information for the material. This node is usually * loaded from the $FG_ROOT/materials.xml file. */ - SGMaterial( const string &fg_root, const SGPropertyNode *props); + SGMaterial( const std::string &fg_root, const SGPropertyNode *props); /** @@ -88,7 +92,7 @@ public: * @param texture_path A string containing an absolute path * to a texture file (usually RGB). */ - SGMaterial( const string &texpath ); + SGMaterial( const std::string &texpath ); /** @@ -117,7 +121,7 @@ public: * Get the textured state. */ osg::StateSet *get_state (int n = -1); - + simgear::Effect *get_effect(int n = -1); /** * Get the number of textures assigned to this material. @@ -188,7 +192,7 @@ public: * * @return the texture to use for trees. */ - inline string get_tree_texture () const { return tree_texture; } + inline std::string get_tree_texture () const { return tree_texture; } /** * Return if the surface material is solid, if it is not solid, a fluid @@ -219,12 +223,12 @@ public: /** * Get the list of names for this material */ - const vector& get_names() const { return _names; } + const std::vector& get_names() const { return _names; } /** * add the given name to the list of names this material is known */ - void add_name(const string& name) { _names.push_back(name); } + void add_name(const std::string& name) { _names.push_back(name); } /** * Get the number of randomly-placed objects defined for this material. @@ -241,7 +245,7 @@ public: /** * Return pointer to glyph class, or 0 if it doesn't exist. */ - SGMaterialGlyph * get_glyph (const string& name) const; + SGMaterialGlyph * get_glyph (const std::string& name) const; void set_light_color(const SGVec4f& color) { emission = color; } @@ -272,10 +276,10 @@ protected: protected: struct _internal_state { - _internal_state( osg::StateSet *s, const string &t, bool l ) - : state(s), texture_path(t), texture_loaded(l) {} + _internal_state( osg::StateSet *s, const std::string &t, bool l ); osg::ref_ptr state; - string texture_path; + osg::ref_ptr effect; + std::string texture_path; bool texture_loaded; }; @@ -287,7 +291,7 @@ private: //////////////////////////////////////////////////////////////////// // texture status - vector<_internal_state> _status; + std::vector<_internal_state> _status; // Round-robin counter mutable unsigned int _current_ptr; @@ -339,23 +343,23 @@ private: double shininess; // the list of names for this material. May be empty. - vector _names; + std::vector _names; - vector > object_groups; + std::vector > object_groups; // taxiway-/runway-sign texture elements - map > glyphs; + std::map > glyphs; // Tree texture, typically a strip of applicable tree textures - string tree_texture; + std::string tree_texture; //////////////////////////////////////////////////////////////////// // Internal constructors and methods. //////////////////////////////////////////////////////////////////// - SGMaterial( const string &fg_root, const SGMaterial &mat ); // unimplemented + SGMaterial( const std::string &fg_root, const SGMaterial &mat ); // unimplemented - void read_properties( const string &fg_root, const SGPropertyNode *props ); + void read_properties( const std::string &fg_root, const SGPropertyNode *props ); void build_state( bool defer_tex_load ); void set_state( osg::StateSet *s ); diff --git a/simgear/scene/material/matlib.cxx b/simgear/scene/material/matlib.cxx index b20ccb44..6f5d10bf 100644 --- a/simgear/scene/material/matlib.cxx +++ b/simgear/scene/material/matlib.cxx @@ -58,6 +58,8 @@ #include "mat.hxx" +#include "Effect.hxx" +#include "Technique.hxx" #include "matlib.hxx" using std::string; diff --git a/simgear/scene/sky/cloud.cxx b/simgear/scene/sky/cloud.cxx index 0addf208..55f10f5d 100644 --- a/simgear/scene/sky/cloud.cxx +++ b/simgear/scene/sky/cloud.cxx @@ -485,6 +485,9 @@ SGCloudLayer::rebuild() layer_states[SG_CLOUD_CLEAR] = 0; layer_states2[SG_CLOUD_CLEAR] = 0; +#if 0 + // experimental optimization that may not make any difference + // at all :/ osg::CopyOp copyOp; for (int i = 0; i < SG_MAX_CLOUD_COVERAGES; ++i) { StateAttributeFactory *saf = StateAttributeFactory::instance(); @@ -495,9 +498,7 @@ SGCloudLayer::rebuild() layer_states2[i]->setAttribute(saf ->getCullFaceBack()); } } - // OSGFIXME -// SGNewCloud::loadTextures(texture_path.str()); -// layer3D->buildTestLayer(); +#endif } scale = 4000.0; diff --git a/simgear/scene/tgdb/obj.cxx b/simgear/scene/tgdb/obj.cxx index f366d758..2efad952 100644 --- a/simgear/scene/tgdb/obj.cxx +++ b/simgear/scene/tgdb/obj.cxx @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include #include #include @@ -367,18 +369,26 @@ struct SGTileGeometryBin { if (materialTriangleMap.empty()) return 0; - osg::Geode* geode = new osg::Geode; + EffectGeode* eg = 0; + osg::Group* group = (materialTriangleMap.size() > 1 ? new osg::Group : 0); + //osg::Geode* geode = new osg::Geode; SGMaterialTriangleMap::const_iterator i; for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) { osg::Geometry* geometry = i->second.buildGeometry(); SGMaterial *mat = 0; if (matlib) mat = matlib->find(i->first); + eg = new EffectGeode; if (mat) - geometry->setStateSet(mat->get_state()); - geode->addDrawable(geometry); + eg->setEffect(mat->get_effect()); + eg->addDrawable(geometry); + if (group) + group->addChild(eg); } - return geode; + if (group) + return group; + else + return eg; } void computeRandomSurfaceLights(SGMaterialLib* matlib) -- 2.39.5