image_overlay.hpp
Go to the documentation of this file.
1 #ifndef RADIAL_MENU_RVIZ_IMAGE_OVERLAY_HPP
2 #define RADIAL_MENU_RVIZ_IMAGE_OVERLAY_HPP
3 
4 #include <string>
5 
6 #include <ros/console.h>
7 
8 #include <OGRE/OgreHardwarePixelBuffer.h>
9 #include <OGRE/OgreMaterial.h>
10 #include <OGRE/OgreMaterialManager.h>
11 #include <OGRE/OgrePixelFormat.h>
12 #include <OGRE/OgreTechnique.h>
13 #include <OGRE/OgreTexture.h>
14 #include <OGRE/OgreTextureManager.h>
15 #include <OGRE/Overlay/OgreOverlayManager.h>
16 #include <OGRE/Overlay/OgrePanelOverlayElement.h>
17 
18 #include <QColor>
19 #include <QImage>
20 #include <QPoint>
21 #include <QSize>
22 
23 #include <boost/lexical_cast.hpp>
24 
25 namespace radial_menu_rviz {
26 
27 class ImageOverlay {
28 public:
30  // use the address of this instance as a name suffix to make names unique
31  suffix_ = boost::lexical_cast< std::string >(this);
32 
33  material_ = Ogre::MaterialManager::getSingleton().create(
34  "ImageOverlayPanelMaterial_" + suffix_,
35  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
36 
37  panel_ = static_cast< Ogre::PanelOverlayElement * >(
38  Ogre::OverlayManager::getSingleton().createOverlayElement("Panel",
39  "ImageOverlayPanel_" + suffix_));
40  panel_->setMetricsMode(Ogre::GMM_PIXELS); // enable positioning & sizing in pixels
41  panel_->setMaterialName(material_->getName());
42 
43  overlay_ = Ogre::OverlayManager::getSingleton().create("ImageOverlay_" + suffix_);
44  overlay_->add2D(panel_);
45 
46  //
47  setOrigin(QPoint(0, 0));
48  setAlignment(0);
49  setImage(QImage());
50  }
51 
52  virtual ~ImageOverlay() {
53  Ogre::OverlayManager::getSingleton().destroy(overlay_);
54  overlay_ = NULL;
55 
56  Ogre::OverlayManager::getSingleton().destroyOverlayElement(panel_);
57  panel_ = NULL;
58 
59  Ogre::MaterialManager::getSingleton().remove(material_->getName());
60  material_.setNull();
61 
62  if (!texture_.isNull()) {
63  Ogre::TextureManager::getSingleton().remove(texture_->getName());
64  texture_.setNull();
65  }
66  }
67 
68  void show() { overlay_->show(); }
69 
70  void hide() { overlay_->hide(); }
71 
72  void setOrigin(const QPoint &pos) { origin_ = pos; }
73 
74  void setAlignment(const int flags) {
75  alignment_ = flags;
76  // if no horizontal alignment flags, use Qt::AlignLeft
77  if (!(alignment_ & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter))) {
78  alignment_ |= Qt::AlignLeft;
79  }
80  // if no vertical alignment flags, use Qt::AlignTop
81  if (!(alignment_ & (Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter))) {
82  alignment_ |= Qt::AlignTop;
83  }
84  }
85 
86  void setImage(const QImage &unformatted_image) {
87  // format the given image
88  if (unformatted_image.width() == 0 || unformatted_image.height() == 0) {
89  image_ = formattedImage(QSize(1, 1), Qt::transparent);
90  } else if (unformatted_image.format() != QImage::Format_ARGB32) {
91  image_ = unformatted_image.convertToFormat(QImage::Format_ARGB32);
92  } else {
93  image_ = unformatted_image;
94  }
95  }
96 
97  void update() {
98  // destroy the current texture if size are diffrent
99  // because we cannot change size of texture after creation
100  if (!texture_.isNull() &&
101  (image_.width() != texture_->getWidth() || image_.height() != texture_->getHeight())) {
102  material_->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
103  Ogre::TextureManager::getSingleton().remove(texture_->getName());
104  texture_.setNull();
105  }
106 
107  // create a new texture if not exists
108  if (texture_.isNull()) {
109  texture_ = Ogre::TextureManager::getSingleton().createManual(
110  "ImageOverlayPanelMaterialTexture_" + suffix_,
111  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D,
112  image_.width(), image_.height(), /* num of mipmaps = */ 0, Ogre::PF_A8R8G8B8);
113  // associate the texture & material
114  material_->getTechnique(0)->getPass(0)->createTextureUnitState(texture_->getName());
115  material_->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
116  // match size of the texture & panel to show the entire area of texture on the panel
117  panel_->setDimensions(texture_->getWidth(), texture_->getHeight());
118  }
119 
120  // set top-left position of the panel according to the alignment
121  if (alignment_ & Qt::AlignLeft) {
122  panel_->setLeft(origin_.x());
123  } else if (alignment_ & Qt::AlignRight) {
124  panel_->setLeft(origin_.x() - panel_->getWidth());
125  } else if (alignment_ & Qt::AlignHCenter) {
126  panel_->setLeft(origin_.x() - panel_->getWidth() / 2);
127  }
128  if (alignment_ & Qt::AlignTop) {
129  panel_->setTop(origin_.y());
130  } else if (alignment_ & Qt::AlignBottom) {
131  panel_->setTop(origin_.y() - panel_->getHeight());
132  } else if (alignment_ & Qt::AlignVCenter) {
133  panel_->setTop(origin_.y() - panel_->getHeight() / 2);
134  }
135 
136  // copy pixel data from the given image to the texture
137  {
138  const Ogre::HardwarePixelBufferSharedPtr buffer(texture_->getBuffer());
139  buffer->lock(Ogre::HardwareBuffer::HBL_NORMAL);
140  std::memcpy(buffer->getCurrentLock().data, image_.constBits(), buffer->getSizeInBytes());
141  buffer->unlock();
142  }
143  }
144 
145  // helper function to create QImage in the expected format
146  static QImage formattedImage(const QSize &size, const QColor &color) {
147  QImage image(size, QImage::Format_ARGB32);
148  image.fill(color);
149  return image;
150  }
151 
152 private:
153  std::string suffix_;
154  Ogre::Overlay *overlay_;
155  Ogre::PanelOverlayElement *panel_;
156  Ogre::MaterialPtr material_;
157  Ogre::TexturePtr texture_;
158 
159  QPoint origin_;
161  QImage image_;
162 };
163 
164 } // namespace radial_menu_rviz
165 
166 #endif
#define NULL
void setAlignment(const int flags)
void setImage(const QImage &unformatted_image)
static QImage formattedImage(const QSize &size, const QColor &color)
Ogre::PanelOverlayElement * panel_
void setOrigin(const QPoint &pos)


radial_menu_rviz
Author(s):
autogenerated on Mon Feb 28 2022 23:22:04