From 2263823f7574a86687994535a02b6a2376b843b5 Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Sun, 9 Dec 2012 23:08:04 +0100 Subject: [PATCH] Create new FBO if Canvas render target size chanages As doesnt seem to work to just resize the texture, if changing the size of the Canvas render target a new FBO is created and placed on all active placements. --- simgear/canvas/Canvas.cxx | 39 ++++++++++++++++++++++++++------------ simgear/canvas/Canvas.hxx | 7 ++++--- simgear/canvas/ODGauge.cxx | 28 +++++++++++++++++++++++---- simgear/canvas/ODGauge.hxx | 2 ++ 4 files changed, 57 insertions(+), 19 deletions(-) diff --git a/simgear/canvas/Canvas.cxx b/simgear/canvas/Canvas.cxx index c2882ebf..8d3059cb 100644 --- a/simgear/canvas/Canvas.cxx +++ b/simgear/canvas/Canvas.cxx @@ -159,15 +159,30 @@ namespace canvas //---------------------------------------------------------------------------- void Canvas::update(double delta_time_sec) { - if( !_texture.serviceable() ) - { - if( _status != STATUS_OK ) - return; + if( (!_texture.serviceable() && _status != STATUS_DIRTY) + || (_status & CREATE_FAILED) ) + return; + if( _status == STATUS_DIRTY ) + { _texture.setSize(_size_x, _size_y); - _texture.useImageCoords(true); - _texture.useStencil(true); - _texture.allocRT(/*_camera_callback*/); + + if( !_texture.serviceable() ) + { + _texture.useImageCoords(true); + _texture.useStencil(true); + _texture.allocRT(/*_camera_callback*/); + } + else + { + // Resizing causes a new texture to be created so we need to reapply all + // existing placements + for(size_t i = 0; i < _placements.size(); ++i) + { + if( !_placements[i].empty() ) + _dirty_placements.push_back( _placements[i].front()->getProps() ); + } + } osg::Camera* camera = _texture.getCamera(); @@ -183,6 +198,8 @@ namespace canvas if( _texture.serviceable() ) { setStatusFlags(STATUS_OK); + setStatusFlags(STATUS_DIRTY, false); + _render_dirty = true; } else { @@ -273,8 +290,7 @@ namespace canvas if( _size_x == sx ) return; _size_x = sx; - - // TODO resize if texture already allocated + setStatusFlags(STATUS_DIRTY); if( _size_x <= 0 ) setStatusFlags(MISSING_SIZE_X); @@ -291,8 +307,7 @@ namespace canvas if( _size_y == sy ) return; _size_y = sy; - - // TODO resize if texture already allocated + setStatusFlags(STATUS_DIRTY); if( _size_y <= 0 ) setStatusFlags(MISSING_SIZE_Y); @@ -545,7 +560,7 @@ namespace canvas _status_msg = "Missing size-y"; else if( _status & CREATE_FAILED ) _status_msg = "Creating render target failed"; - else if( _status == STATUS_OK && !_texture.serviceable() ) + else if( _status == STATUS_DIRTY ) _status_msg = "Creation pending..."; else _status_msg = "Ok"; diff --git a/simgear/canvas/Canvas.hxx b/simgear/canvas/Canvas.hxx index 4a3187ff..f53c7492 100644 --- a/simgear/canvas/Canvas.hxx +++ b/simgear/canvas/Canvas.hxx @@ -46,9 +46,10 @@ namespace canvas enum StatusFlags { STATUS_OK, - MISSING_SIZE_X = 0x0001, - MISSING_SIZE_Y = 0x0002, - CREATE_FAILED = 0x0004 + STATUS_DIRTY = 1, + MISSING_SIZE_X = STATUS_DIRTY << 1, + MISSING_SIZE_Y = MISSING_SIZE_X << 1, + CREATE_FAILED = MISSING_SIZE_Y << 1 }; /** diff --git a/simgear/canvas/ODGauge.cxx b/simgear/canvas/ODGauge.cxx index 8b27c06f..b59efc6a 100644 --- a/simgear/canvas/ODGauge.cxx +++ b/simgear/canvas/ODGauge.cxx @@ -70,8 +70,7 @@ namespace canvas //---------------------------------------------------------------------------- ODGauge::~ODGauge() { - if( camera.valid() && _system_adapter ) - _system_adapter->removeCamera(camera.get()); + clear(); } //---------------------------------------------------------------------------- @@ -86,8 +85,10 @@ namespace canvas _size_x = size_x; _size_y = size_y < 0 ? size_x : size_y; - if( texture.valid() ) - texture->setTextureSize(_size_x, _size_x); + if( serviceable() ) + reinit(); + else if( texture ) + texture->setTextureSize(_size_x, _size_y); } //---------------------------------------------------------------------------- @@ -217,6 +218,25 @@ namespace canvas rtAvailable = true; } + //---------------------------------------------------------------------------- + void ODGauge::reinit() + { + osg::NodeCallback* cull_callback = camera ? camera->getCullCallback() : 0; + clear(); + allocRT(cull_callback); + } + + //---------------------------------------------------------------------------- + void ODGauge::clear() + { + if( camera.valid() && _system_adapter ) + _system_adapter->removeCamera(camera.get()); + camera.release(); + texture.release(); + + rtAvailable = false; + } + //---------------------------------------------------------------------------- void ODGauge::updateCoordinateFrame() { diff --git a/simgear/canvas/ODGauge.hxx b/simgear/canvas/ODGauge.hxx index 5a07d69e..3005132c 100644 --- a/simgear/canvas/ODGauge.hxx +++ b/simgear/canvas/ODGauge.hxx @@ -123,6 +123,8 @@ namespace canvas // Real initialization function. Bad name. void allocRT(osg::NodeCallback* camera_cull_callback = 0); + void reinit(); + void clear(); protected: -- 2.39.5