diff --git a/src/rviz/default_plugin/camera_display.cpp b/src/rviz/default_plugin/camera_display.cpp index 49abcfea8f..8afa2b158b 100644 --- a/src/rviz/default_plugin/camera_display.cpp +++ b/src/rviz/default_plugin/camera_display.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +103,8 @@ CameraDisplay::CameraDisplay() SLOT(forceRender())); zoom_property_->setMin(0.00001); zoom_property_->setMax(100000); + + has_run_once_ = false; } CameraDisplay::~CameraDisplay() @@ -127,8 +130,15 @@ void CameraDisplay::onInitialize() { ImageDisplayBase::onInitialize(); - bg_scene_node_ = scene_node_->createChildSceneNode(); - fg_scene_node_ = scene_node_->createChildSceneNode(); + { + static uint32_t count = 0; + std::stringstream ss; + ss << "CameraDisplay" << count++; + camera_scene_manager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, ss.str()); + } + + bg_scene_node_ = camera_scene_manager_->getRootSceneNode()->createChildSceneNode(); + fg_scene_node_ = camera_scene_manager_->getRootSceneNode()->createChildSceneNode(); { static int count = 0; @@ -189,6 +199,7 @@ void CameraDisplay::onInitialize() render_panel_->getRenderWindow()->setActive(false); render_panel_->resize(640, 480); render_panel_->initialize(context_->getSceneManager(), context_); + // render_panel_->initialize(camera_scene_manager_, context_); setAssociatedWidget(render_panel_); @@ -212,8 +223,16 @@ void CameraDisplay::onInitialize() void CameraDisplay::preRenderTargetUpdate(const Ogre::RenderTargetEvent& /*evt*/) { QString image_position = image_position_property_->getString(); - bg_scene_node_->setVisible(caminfo_ok_ && (image_position == BACKGROUND || image_position == BOTH)); - fg_scene_node_->setVisible(caminfo_ok_ && (image_position == OVERLAY || image_position == BOTH)); + + if (has_run_once_) + { + fg_scene_node_->setVisible(caminfo_ok_ && (image_position == OVERLAY || image_position == BOTH)); + bg_scene_node_->setVisible(caminfo_ok_ && (image_position == BACKGROUND || image_position == BOTH)); + } + else + { + has_run_once_ = true; + } // set view flags on all displays visibility_property_->update(); diff --git a/src/rviz/default_plugin/camera_display.h b/src/rviz/default_plugin/camera_display.h index 175a3a2402..ccd4d6f3e9 100644 --- a/src/rviz/default_plugin/camera_display.h +++ b/src/rviz/default_plugin/camera_display.h @@ -96,6 +96,8 @@ class CameraDisplay : public ImageDisplayBase, public Ogre::RenderTargetListener ROSImageTexture texture_; RenderPanel* render_panel_; + Ogre::SceneManager* camera_scene_manager_; + private Q_SLOTS: void forceRender(); void updateAlpha(); @@ -135,6 +137,8 @@ private Q_SLOTS: bool force_render_; uint32_t vis_bit_; + + bool has_run_once_; }; } // namespace rviz diff --git a/src/rviz/default_plugin/image_display.cpp b/src/rviz/default_plugin/image_display.cpp index 3b5d50ceac..e424ea68aa 100644 --- a/src/rviz/default_plugin/image_display.cpp +++ b/src/rviz/default_plugin/image_display.cpp @@ -72,6 +72,7 @@ ImageDisplay::ImageDisplay() : ImageDisplayBase(), texture_() this, SLOT(updateNormalizeOptions())); got_float_image_ = false; + has_run_once_ = false; } void ImageDisplay::onInitialize() @@ -114,12 +115,13 @@ void ImageDisplay::onInitialize() screen_rect_->setBoundingBox(aabInf); setMaterial(*screen_rect_, material_); img_scene_node_->attachObject(screen_rect_); + img_scene_node_->setVisible(false); } render_panel_ = new RenderPanel(); + render_panel_->getRenderWindow()->addListener(this); render_panel_->getRenderWindow()->setAutoUpdated(false); render_panel_->getRenderWindow()->setActive(false); - render_panel_->resize(640, 480); render_panel_->initialize(img_scene_manager_, context_); @@ -136,12 +138,32 @@ ImageDisplay::~ImageDisplay() { if (initialized()) { + render_panel_->getRenderWindow()->removeListener(this); + delete render_panel_; delete screen_rect_; removeAndDestroyChildNode(img_scene_node_->getParentSceneNode(), img_scene_node_); } } +void ImageDisplay::preRenderTargetUpdate(const Ogre::RenderTargetEvent& /*evt*/) +{ + if (has_run_once_) + { + img_scene_node_->setVisible(true); + } + else + { + has_run_once_ = true; + img_scene_node_->setVisible(false); + } +} + +void ImageDisplay::postRenderTargetUpdate(const Ogre::RenderTargetEvent& /*evt*/) +{ + img_scene_node_->setVisible(false); +} + void ImageDisplay::onEnable() { ImageDisplayBase::subscribe(); diff --git a/src/rviz/default_plugin/image_display.h b/src/rviz/default_plugin/image_display.h index 88492c191e..e5b1335bf7 100644 --- a/src/rviz/default_plugin/image_display.h +++ b/src/rviz/default_plugin/image_display.h @@ -59,7 +59,7 @@ namespace rviz * \class ImageDisplay * */ -class ImageDisplay : public ImageDisplayBase +class ImageDisplay : public ImageDisplayBase, public Ogre::RenderTargetListener { Q_OBJECT public: @@ -71,6 +71,10 @@ class ImageDisplay : public ImageDisplayBase void update(float wall_dt, float ros_dt) override; void reset() override; + // Overrides from Ogre::RenderTargetListener + void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) override; + void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) override; + public Q_SLOTS: virtual void updateNormalizeOptions(); @@ -98,6 +102,8 @@ public Q_SLOTS: FloatProperty* max_property_; IntProperty* median_buffer_size_property_; bool got_float_image_; + + bool has_run_once_; }; } // namespace rviz diff --git a/src/rviz/ogre_helpers/render_system.cpp b/src/rviz/ogre_helpers/render_system.cpp index 14d83396c3..d1a500d305 100644 --- a/src/rviz/ogre_helpers/render_system.cpp +++ b/src/rviz/ogre_helpers/render_system.cpp @@ -423,7 +423,7 @@ Ogre::RenderWindow* RenderSystem::makeRenderWindow(WindowIDType window_id, // Created a non-stereo window. Discard it and try again (below) // without the stereo parameter. ogre_root_->detachRenderTarget(window); - window->destroy(); + ogre_root_->destroyRenderTarget(window); window = nullptr; stream << "x"; is_stereo = false; @@ -480,6 +480,7 @@ Ogre::RenderWindow* RenderSystem::tryMakeRenderWindow(const std::string& name, if (x_baddrawable_error) { ogre_root_->detachRenderTarget(window); + ogre_root_->destroyRenderTarget(window); window = nullptr; x_baddrawable_error = false; } diff --git a/src/rviz/render_panel.cpp b/src/rviz/render_panel.cpp index 5532741d4e..10fc63314b 100644 --- a/src/rviz/render_panel.cpp +++ b/src/rviz/render_panel.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -100,6 +101,12 @@ void RenderPanel::leaveEvent(QEvent* /*event*/) } } +void RenderPanel::resizeEvent(QResizeEvent* event) +{ + QWidget::resizeEvent(event); + render_window_->windowMovedOrResized(); +} + void RenderPanel::onRenderWindowMouseEvents(QMouseEvent* event) { int last_x = mouse_x_; diff --git a/src/rviz/render_panel.h b/src/rviz/render_panel.h index 2ce29c6f87..e1ef904e98 100644 --- a/src/rviz/render_panel.h +++ b/src/rviz/render_panel.h @@ -118,6 +118,8 @@ class RenderPanel : public QtOgreRenderWindow, public Ogre::SceneManager::Listen /// Called when any mouse event happens inside the render window void onRenderWindowMouseEvents(QMouseEvent* event); + void resizeEvent(QResizeEvent* event) override; + // QWidget mouse events all get sent to onRenderWindowMouseEvents(). // QMouseEvent.type() distinguishes them later. void mouseMoveEvent(QMouseEvent* event) override