qt_ogre_render_window.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 #include "qt_ogre_render_window.h"
30 #include "orthographic.h"
31 #include "render_system.h"
32 
33 #include <OgreRoot.h>
34 #include <OgreViewport.h>
35 #include <OgreCamera.h>
36 #include <OgreRenderWindow.h>
37 #include <OgreStringConverter.h>
38 #include <OgreGpuProgramManager.h>
39 #include <OgreRenderTargetListener.h>
40 
41 #include <ros/console.h>
42 #include <ros/assert.h>
43 
44 #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
45 #include <stdlib.h>
46 #endif
47 
48 namespace rviz
49 {
51  : RenderWidget(RenderSystem::get(), parent)
52  , viewport_(nullptr)
53  , ogre_root_(RenderSystem::get()->root())
54  , ortho_scale_(1.0f)
55  , auto_render_(true)
56  , camera_(nullptr)
57  , overlays_enabled_(true) // matches the default of Ogre::Viewport.
58  , background_color_(Ogre::ColourValue::Black) // matches the default of Ogre::Viewport.
59  , stereo_enabled_(false)
60  , rendering_stereo_(false)
61  , left_camera_(nullptr)
62  , right_camera_(nullptr)
63  , right_viewport_(nullptr)
64 {
65  render_window_->setVisible(true);
66  render_window_->setAutoUpdated(true);
67 
68  viewport_ = render_window_->addViewport(camera_);
69  viewport_->setOverlaysEnabled(overlays_enabled_);
70  viewport_->setBackgroundColour(background_color_);
71 
72 #if OGRE_STEREO_ENABLE
73  viewport_->setDrawBuffer(Ogre::CBT_BACK);
74 #endif
75  enableStereo(true);
76 
78 }
79 
81 {
82  enableStereo(false); // free stereo resources
83 }
84 
85 //------------------------------------------------------------------------------
87 {
88  bool was_enabled = stereo_enabled_;
89  stereo_enabled_ = enable;
90  setupStereo();
91  return was_enabled;
92 }
93 
95 {
96  bool render_stereo = stereo_enabled_ && RenderSystem::get()->isStereoSupported();
97 
98  if (render_stereo == rendering_stereo_)
99  return;
100 
101  rendering_stereo_ = render_stereo;
102 
103  if (rendering_stereo_)
104  {
105  right_viewport_ = render_window_->addViewport(nullptr, 1);
106 #if OGRE_STEREO_ENABLE
107  right_viewport_->setDrawBuffer(Ogre::CBT_BACK_RIGHT);
108  viewport_->setDrawBuffer(Ogre::CBT_BACK_LEFT);
109 #endif
110 
113  if (camera_)
115 
116  // addListener causes preViewportUpdate() to be called when rendering.
117  render_window_->addListener(this);
118  }
119  else
120  {
121  render_window_->removeListener(this);
122  render_window_->removeViewport(1);
123  right_viewport_ = nullptr;
124 
125 #if OGRE_STEREO_ENABLE
126  viewport_->setDrawBuffer(Ogre::CBT_BACK);
127 #endif
128 
129  if (left_camera_)
130  left_camera_->getSceneManager()->destroyCamera(left_camera_);
131  left_camera_ = nullptr;
132  if (right_camera_)
133  right_camera_->getSceneManager()->destroyCamera(right_camera_);
134  right_camera_ = nullptr;
135  }
136 }
137 
138 // this is called just before rendering either viewport when stereo is enabled.
139 void QtOgreRenderWindow::preViewportUpdate(const Ogre::RenderTargetViewportEvent& evt)
140 {
141  Ogre::Viewport* viewport = evt.source;
142 
143  const Ogre::Vector2& offset = camera_->getFrustumOffset();
144  const Ogre::Vector3 pos = camera_->getPosition();
145  const Ogre::Vector3 right = camera_->getRight();
146  const Ogre::Vector3 up = camera_->getUp();
147 
148  if (viewport == right_viewport_)
149  {
150  if (camera_->getProjectionType() != Ogre::PT_PERSPECTIVE || !right_camera_)
151  {
152  viewport->setCamera(camera_);
153  return;
154  }
155 
156  Ogre::Vector3 newpos = pos + right * offset.x + up * offset.y;
157 
158  right_camera_->synchroniseBaseSettingsWith(camera_);
159  right_camera_->setFrustumOffset(-offset);
160  right_camera_->setPosition(newpos);
161  viewport->setCamera(right_camera_);
162  }
163  else if (viewport == viewport_)
164  {
165  if (camera_->getProjectionType() != Ogre::PT_PERSPECTIVE || !left_camera_)
166  {
167  viewport->setCamera(camera_);
168  return;
169  }
170 
171  Ogre::Vector3 newpos = pos - right * offset.x - up * offset.y;
172 
173  left_camera_->synchroniseBaseSettingsWith(camera_);
174  left_camera_->setFrustumOffset(offset);
175  left_camera_->setPosition(newpos);
176  viewport->setCamera(left_camera_);
177  }
178  else
179  {
180  ROS_WARN("Begin rendering to unknown viewport.");
181  }
182 }
183 
184 void QtOgreRenderWindow::postViewportUpdate(const Ogre::RenderTargetViewportEvent& evt)
185 {
186  Ogre::Viewport* viewport = evt.source;
187 
188  if (viewport == right_viewport_)
189  {
190  // nothing to do here
191  }
192  else if (viewport == viewport_)
193  {
194  viewport->setCamera(camera_);
195  }
196  else
197  {
198  ROS_WARN("End rendering to unknown viewport.");
199  }
200 
201  if (!right_camera_->isCustomProjectionMatrixEnabled())
202  {
203  right_camera_->synchroniseBaseSettingsWith(camera_);
204  right_camera_->setFrustumOffset(-camera_->getFrustumOffset());
205  }
206  right_viewport_->setCamera(right_camera_);
207 }
208 
209 Ogre::Viewport* QtOgreRenderWindow::getViewport() const
210 {
211  return viewport_;
212 }
213 
214 void QtOgreRenderWindow::setCamera(Ogre::Camera* camera)
215 {
216  if (camera)
217  {
218  camera_ = camera;
219  viewport_->setCamera(camera);
220 
222 
224  {
225  left_camera_ = camera_->getSceneManager()->createCamera(camera_->getName() + "-left");
226  }
228  {
229  right_camera_ = camera_->getSceneManager()->createCamera(camera_->getName() + "-right");
230  }
231 
232  update();
233  }
234 }
235 
236 void QtOgreRenderWindow::setOverlaysEnabled(bool overlays_enabled)
237 {
238  overlays_enabled_ = overlays_enabled;
239  viewport_->setOverlaysEnabled(overlays_enabled);
240  if (right_viewport_)
241  {
242  right_viewport_->setOverlaysEnabled(overlays_enabled);
243  }
244 }
245 
246 void QtOgreRenderWindow::setBackgroundColor(Ogre::ColourValue background_color)
247 {
248  background_color_ = background_color;
249  viewport_->setBackgroundColour(background_color);
250  if (right_viewport_)
251  {
252  right_viewport_->setBackgroundColour(background_color);
253  }
254 }
255 
257 {
258  if (camera_)
259  {
260  camera_->setAspectRatio(Ogre::Real(width()) / Ogre::Real(height()));
261  if (right_camera_)
262  {
263  right_camera_->setAspectRatio(Ogre::Real(width()) / Ogre::Real(height()));
264  }
265 
266  if (camera_->getProjectionType() == Ogre::PT_ORTHOGRAPHIC)
267  {
268  Ogre::Matrix4 proj;
269  buildScaledOrthoMatrix(proj, -width() / ortho_scale_ / 2, width() / ortho_scale_ / 2,
270  -height() / ortho_scale_ / 2, height() / ortho_scale_ / 2,
271  camera_->getNearClipDistance(), camera_->getFarClipDistance());
272  camera_->setCustomProjectionMatrix(true, proj);
273  }
274  }
275 }
276 
278 {
279  ortho_scale_ = scale;
280 
282 }
283 
284 void QtOgreRenderWindow::setPreRenderCallback(boost::function<void()> func)
285 {
286  pre_render_callback_ = func;
287 }
288 
289 void QtOgreRenderWindow::setPostRenderCallback(boost::function<void()> func)
290 {
291  post_render_callback_ = func;
292 }
293 
294 //------------------------------------------------------------------------------
295 void QtOgreRenderWindow::paintEvent(QPaintEvent* /*e*/)
296 {
298  {
300  {
302  }
303 
304  if (ogre_root_->_fireFrameStarted())
305  {
306 #if (OGRE_VERSION_MAJOR >= 1 && OGRE_VERSION_MINOR >= 6)
307  ogre_root_->_fireFrameRenderingQueued();
308 #endif
309 
310  render_window_->update();
311 
312  ogre_root_->_fireFrameEnded();
313  }
314 
316  {
318  }
319  }
320 }
321 
322 //------------------------------------------------------------------------------
323 void QtOgreRenderWindow::resizeEvent(QResizeEvent* event)
324 {
326 
327  if (render_window_)
328  {
330 
331  if (auto_render_)
332  {
333  update();
334  }
335  }
336 }
337 
338 } // namespace rviz
root
boost::function< void()> pre_render_callback_
Functor which is called before each render.
void postViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override
f
bool enableStereo(bool enable)
Enable or disable stereo rendering If stereo is not supported this is ignored.
static RenderSystem * get()
void paintEvent(QPaintEvent *e) override
#define ROS_WARN(...)
Ogre::RenderWindow * render_window_
Definition: render_widget.h:68
def get(url)
QtOgreRenderWindow(QWidget *parent=nullptr)
void update(const std::string &key, const XmlRpc::XmlRpcValue &v)
void preViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override
virtual void setPreRenderCallback(boost::function< void()> func)
void resizeEvent(QResizeEvent *e) override
Ogre::Viewport * getViewport() const
void setBackgroundColor(Ogre::ColourValue color)
Ogre::ColourValue background_color_
boost::function< void()> post_render_callback_
Functor which is called after each render.
void buildScaledOrthoMatrix(Ogre::Matrix4 &proj, float left, float right, float bottom, float top, float near, float far)
void resizeEvent(QResizeEvent *event) override
void setupStereo()
Prepare to render in stereo if enabled and supported.
void setCamera(Ogre::Camera *camera)
void setOverlaysEnabled(bool overlays_enabled)
virtual void setPostRenderCallback(boost::function< void()> func)
void setOrthoScale(float scale)
Set the scale of the orthographic window. Only valid for an orthographic camera.


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Mon Aug 15 2022 02:05:17