From 70cdc3e3af90714537bc4b5c9fce64939623b2bd Mon Sep 17 00:00:00 2001 From: gwaldron Date: Mon, 12 Nov 2018 12:54:39 -0500 Subject: [PATCH] Fix a bug in which the rex elevation texture was not getting applied for subsequent layers --- .../engine_rex/DrawTileCommand.cpp | 6 ++-- .../engine_rex/LayerDrawable.cpp | 34 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/osgEarthDrivers/engine_rex/DrawTileCommand.cpp b/src/osgEarthDrivers/engine_rex/DrawTileCommand.cpp index 9ae683810a..1130686eef 100644 --- a/src/osgEarthDrivers/engine_rex/DrawTileCommand.cpp +++ b/src/osgEarthDrivers/engine_rex/DrawTileCommand.cpp @@ -78,7 +78,8 @@ DrawTileCommand::draw(osg::RenderInfo& ri, DrawState& dsMaster, osg::Referenced* if (sampler._texture.valid() && !samplerState._texture.isSetTo(sampler._texture.get())) { - state.applyTextureAttribute((*dsMaster._bindings)[s].unit(), sampler._texture.get()); + state.setActiveTextureUnit((*dsMaster._bindings)[s].unit()); + sampler._texture->apply(state); samplerState._texture = sampler._texture.get(); } @@ -109,7 +110,8 @@ DrawTileCommand::draw(osg::RenderInfo& ri, DrawState& dsMaster, osg::Referenced* if (sampler._texture.valid() && !samplerState._texture.isSetTo(sampler._texture.get())) { - state.applyTextureAttribute((*dsMaster._bindings)[s].unit(), sampler._texture.get()); + state.setActiveTextureUnit((*dsMaster._bindings)[s].unit()); + sampler._texture->apply(state); samplerState._texture = sampler._texture.get(); } diff --git a/src/osgEarthDrivers/engine_rex/LayerDrawable.cpp b/src/osgEarthDrivers/engine_rex/LayerDrawable.cpp index a9f3e8fa35..c9c914634f 100644 --- a/src/osgEarthDrivers/engine_rex/LayerDrawable.cpp +++ b/src/osgEarthDrivers/engine_rex/LayerDrawable.cpp @@ -47,6 +47,35 @@ LayerDrawable::~LayerDrawable() setStateSet(0L); } +namespace +{ + // Hack State so we can dirty the texture attrs without dirtying the other + // attributes (as dirtyAllAttributes() would do. + struct StateEx : public osg::State + { + void dirtyAllTextureAttributes() + { + // dirtyAllTextureAttributes. (Don't call state->dirtyAllAttributes because that + // will mess up positional state attributes like light sources) + for (TextureAttributeMapList::iterator tamItr = _textureAttributeMapList.begin(); + tamItr != _textureAttributeMapList.end(); + ++tamItr) + { + osg::State::AttributeMap& attributeMap = *tamItr; + for (osg::State::AttributeMap::iterator aitr = attributeMap.begin(); + aitr != attributeMap.end(); + ++aitr) + { + osg::State::AttributeStack& as = aitr->second; + as.last_applied_attribute = 0; + as.changed = true; + } + } + } + }; +} + + void LayerDrawable::drawImplementation(osg::RenderInfo& ri) const { @@ -76,6 +105,11 @@ LayerDrawable::drawImplementation(osg::RenderInfo& ri) const // necessary when doing custom OpenGL within a Drawable. if (_clearOsgState) { + // Dirty the texture attributes so OSG can properly reset them + // NOTE: cannot call state.dirtyAllAttributes, because that would invalidate + // positional state like light sources! + reinterpret_cast(ri.getState())->dirtyAllTextureAttributes(); + // NOTE: this is a NOOP in OSG 3.5.x, but not in 3.4.x ... Later we will need to // revisit whether to call disableAllVertexArrays() in 3.5.x instead. ri.getState()->dirtyAllVertexArrays();