From 0a1e9206594dc76da41bad83fc53dc26c605ea8b Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Mon, 11 Mar 2013 21:22:43 +0100 Subject: [PATCH] Ensure canvas is updated before displaying image containing a canvas --- simgear/canvas/elements/CanvasImage.cxx | 42 +++++++++++++++++++++++-- simgear/canvas/elements/CanvasImage.hxx | 1 + 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/simgear/canvas/elements/CanvasImage.cxx b/simgear/canvas/elements/CanvasImage.cxx index 9787b232..cbf0055d 100644 --- a/simgear/canvas/elements/CanvasImage.cxx +++ b/simgear/canvas/elements/CanvasImage.cxx @@ -47,9 +47,11 @@ namespace canvas { public: CullCallback(const CanvasWeakPtr& canvas); + void cullNextFrame(); private: CanvasWeakPtr _canvas; + mutable bool _cull_next_frame; virtual bool cull( osg::NodeVisitor* nv, osg::Drawable* drawable, @@ -58,11 +60,18 @@ namespace canvas //---------------------------------------------------------------------------- CullCallback::CullCallback(const CanvasWeakPtr& canvas): - _canvas( canvas ) + _canvas( canvas ), + _cull_next_frame( false ) { } + //---------------------------------------------------------------------------- + void CullCallback::cullNextFrame() + { + _cull_next_frame = true; + } + //---------------------------------------------------------------------------- bool CullCallback::cull( osg::NodeVisitor* nv, osg::Drawable* drawable, @@ -71,8 +80,12 @@ namespace canvas if( !_canvas.expired() ) _canvas.lock()->enableRendering(); - // TODO check if window/image should be culled - return false; + if( !_cull_next_frame ) + // TODO check if window/image should be culled + return false; + + _cull_next_frame = false; + return true; } //---------------------------------------------------------------------------- @@ -288,6 +301,29 @@ namespace canvas } } + //---------------------------------------------------------------------------- + void Image::valueChanged(SGPropertyNode* child) + { + // If the image is switched from invisible to visible, and it shows a + // canvas, we need to delay showing it by one frame to ensure the canvas is + // updated before the image is displayed. + // + // As canvas::Element handles and filters changes to the "visible" property + // we can not check this in Image::childChanged but instead have to override + // Element::valueChanged. + if( !isVisible() + && child->getParent() == _node + && child->getNameString() == "visible" + && child->getBoolValue() ) + { + CullCallback* cb = static_cast(_geom->getCullCallback()); + if( cb ) + cb->cullNextFrame(); + } + + Element::valueChanged(child); + } + //---------------------------------------------------------------------------- void Image::setSrcCanvas(CanvasPtr canvas) { diff --git a/simgear/canvas/elements/CanvasImage.hxx b/simgear/canvas/elements/CanvasImage.hxx index 39813e34..fccc20f5 100644 --- a/simgear/canvas/elements/CanvasImage.hxx +++ b/simgear/canvas/elements/CanvasImage.hxx @@ -48,6 +48,7 @@ namespace canvas virtual ~Image(); virtual void update(double dt); + virtual void valueChanged(SGPropertyNode* child); void setSrcCanvas(CanvasPtr canvas); CanvasWeakPtr getSrcCanvas() const;