qt_ogre_render_window.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2012, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 #include "qt_ogre_render_window.h"
00030 #include "orthographic.h"
00031 #include "render_system.h"
00032 
00033 #include <OgreRoot.h>
00034 #include <OgreViewport.h>
00035 #include <OgreCamera.h>
00036 #include <OgreRenderWindow.h>
00037 #include <OgreStringConverter.h>
00038 #include <OgreGpuProgramManager.h>
00039 #include <OgreRenderTargetListener.h>
00040 
00041 #include <ros/console.h>
00042 #include <ros/assert.h>
00043 
00044 #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
00045 #include <stdlib.h>
00046 #endif
00047 
00048 namespace rviz
00049 {
00050 
00051 QtOgreRenderWindow::QtOgreRenderWindow( QWidget* parent )
00052   : RenderWidget( RenderSystem::get(), parent )
00053   , viewport_( 0 )
00054   , ogre_root_( RenderSystem::get()->root() )
00055   , ortho_scale_( 1.0f )
00056   , auto_render_( true )
00057   , camera_( 0 )
00058   , overlays_enabled_( true ) // matches the default of Ogre::Viewport.
00059   , background_color_( Ogre::ColourValue::Black ) // matches the default of Ogre::Viewport.
00060   , stereo_enabled_( false )
00061   , rendering_stereo_( false )
00062   , left_camera_( 0 )
00063   , right_camera_( 0 )
00064   , right_viewport_( 0 )
00065 {
00066   render_window_->setVisible(true);
00067   render_window_->setAutoUpdated(true);
00068 
00069   viewport_ = render_window_->addViewport( camera_ );
00070   viewport_->setOverlaysEnabled( overlays_enabled_ );
00071   viewport_->setBackgroundColour( background_color_ );
00072 
00073 #if OGRE_STEREO_ENABLE
00074   viewport_->setDrawBuffer(Ogre::CBT_BACK);
00075 #endif
00076   enableStereo(true);
00077 
00078   setCameraAspectRatio();
00079 }
00080 
00081 QtOgreRenderWindow::~QtOgreRenderWindow()
00082 {
00083   enableStereo(false);  // free stereo resources
00084 }
00085 
00086 //------------------------------------------------------------------------------
00087 bool QtOgreRenderWindow::enableStereo (bool enable)
00088 {
00089   bool was_enabled = stereo_enabled_;
00090   stereo_enabled_ = enable;
00091   setupStereo();
00092   return was_enabled;
00093 }
00094 
00095 void QtOgreRenderWindow::setupStereo()
00096 {
00097   bool render_stereo = stereo_enabled_ && RenderSystem::get()->isStereoSupported();
00098 
00099   if (render_stereo == rendering_stereo_)
00100     return;
00101 
00102   rendering_stereo_ = render_stereo;
00103 
00104   if (rendering_stereo_)
00105   {
00106     right_viewport_ = render_window_->addViewport( NULL, 1 );
00107 #if OGRE_STEREO_ENABLE
00108     right_viewport_->setDrawBuffer(Ogre::CBT_BACK_RIGHT);
00109     viewport_->setDrawBuffer(Ogre::CBT_BACK_LEFT);
00110 #endif
00111 
00112     setOverlaysEnabled(overlays_enabled_);
00113     setBackgroundColor(background_color_);
00114     if (camera_)
00115       setCamera(camera_);
00116 
00117     // addListener causes preViewportUpdate() to be called when rendering.
00118     render_window_->addListener(this);
00119   }
00120   else
00121   {
00122     render_window_->removeListener(this);
00123     render_window_->removeViewport(1);
00124     right_viewport_ = NULL;
00125 
00126 #if OGRE_STEREO_ENABLE
00127     viewport_->setDrawBuffer(Ogre::CBT_BACK);
00128 #endif
00129 
00130     if (left_camera_)
00131       left_camera_->getSceneManager()->destroyCamera( left_camera_ );
00132     left_camera_ = NULL;
00133     if (right_camera_)
00134       right_camera_->getSceneManager()->destroyCamera( right_camera_ );
00135     right_camera_ = NULL;
00136   }
00137 
00138 }
00139 
00140 // this is called just before rendering either viewport when stereo is enabled.
00141 void QtOgreRenderWindow::preViewportUpdate(
00142       const Ogre::RenderTargetViewportEvent& evt)
00143 {
00144   Ogre::Viewport* viewport = evt.source;
00145 
00146   const Ogre::Vector2& offset = camera_->getFrustumOffset();
00147   const Ogre::Vector3 pos = camera_->getPosition();
00148   const Ogre::Vector3 right = camera_->getRight();
00149   const Ogre::Vector3 up = camera_->getUp();
00150 
00151   if (viewport == right_viewport_)
00152   {
00153     if (camera_->getProjectionType() != Ogre::PT_PERSPECTIVE || !right_camera_)
00154     {
00155       viewport->setCamera( camera_ );
00156       return;
00157     }
00158 
00159     Ogre::Vector3 newpos = pos
00160                            + right * offset.x
00161                            + up * offset.y;
00162 
00163     right_camera_->synchroniseBaseSettingsWith(camera_);
00164     right_camera_->setFrustumOffset(-offset);
00165     right_camera_->setPosition(newpos);
00166     viewport->setCamera(right_camera_);
00167   }
00168   else if (viewport == viewport_)
00169   {
00170     if (camera_->getProjectionType() != Ogre::PT_PERSPECTIVE || !left_camera_)
00171     {
00172       viewport->setCamera( camera_ );
00173       return;
00174     }
00175 
00176     Ogre::Vector3 newpos = pos
00177                            - right * offset.x
00178                            - up * offset.y;
00179     
00180     left_camera_->synchroniseBaseSettingsWith(camera_);
00181     left_camera_->setFrustumOffset(offset);
00182     left_camera_->setPosition(newpos);
00183     viewport->setCamera(left_camera_);
00184   }
00185   else
00186   {
00187     ROS_WARN("Begin rendering to unknown viewport.");
00188   }
00189 }
00190 
00191 void QtOgreRenderWindow::postViewportUpdate(
00192       const Ogre::RenderTargetViewportEvent& evt)
00193 {
00194   Ogre::Viewport* viewport = evt.source;
00195 
00196   if (viewport == right_viewport_)
00197   {
00198     // nothing to do here
00199   }
00200   else if (viewport == viewport_)
00201   {
00202     viewport->setCamera(camera_);
00203   }
00204   else
00205   {
00206     ROS_WARN("End rendering to unknown viewport.");
00207   }
00208 }
00209 
00210 Ogre::Viewport* QtOgreRenderWindow::getViewport () const
00211 {
00212   return viewport_;
00213 }
00214 
00215 void QtOgreRenderWindow::setCamera( Ogre::Camera* camera )
00216 {
00217   if (camera)
00218   {
00219     camera_ = camera;
00220     viewport_->setCamera( camera );
00221 
00222     setCameraAspectRatio();
00223 
00224     if (camera_ && rendering_stereo_ && !left_camera_)
00225     {
00226       left_camera_ = camera_->getSceneManager()->createCamera(camera_->getName() + "-left");
00227     }
00228     if (camera_ && rendering_stereo_ && !right_camera_)
00229     {
00230       right_camera_ = camera_->getSceneManager()->createCamera(camera_->getName() + "-right");
00231     }
00232 
00233     update();
00234   }
00235 }
00236 
00237 void QtOgreRenderWindow::setOverlaysEnabled( bool overlays_enabled )
00238 {
00239   overlays_enabled_ = overlays_enabled;
00240   viewport_->setOverlaysEnabled( overlays_enabled );
00241   if (right_viewport_)
00242   {
00243     right_viewport_->setOverlaysEnabled( overlays_enabled );
00244   }
00245 }
00246 
00247 void QtOgreRenderWindow::setBackgroundColor( Ogre::ColourValue background_color )
00248 {
00249   background_color_ = background_color;
00250   viewport_->setBackgroundColour( background_color );
00251   if (right_viewport_)
00252   {
00253     right_viewport_->setBackgroundColour( background_color );
00254   }
00255 }
00256 
00257 void QtOgreRenderWindow::setCameraAspectRatio()
00258 {
00259   if ( camera_ )
00260   {
00261     camera_->setAspectRatio( Ogre::Real( width() ) / Ogre::Real( height() ) );
00262 
00263     if ( camera_->getProjectionType() == Ogre::PT_ORTHOGRAPHIC )
00264     {
00265       Ogre::Matrix4 proj;
00266       buildScaledOrthoMatrix( proj,
00267                               -width() / ortho_scale_ / 2, width() / ortho_scale_ / 2,
00268                               -height() / ortho_scale_ / 2, height() / ortho_scale_ / 2,
00269                               camera_->getNearClipDistance(), camera_->getFarClipDistance() );
00270       camera_->setCustomProjectionMatrix(true, proj);
00271     }
00272   }
00273 }
00274 
00275 void QtOgreRenderWindow::setOrthoScale( float scale )
00276 {
00277   ortho_scale_ = scale;
00278 
00279   setCameraAspectRatio();
00280 }
00281 
00282 void QtOgreRenderWindow::setPreRenderCallback( boost::function<void ()> func )
00283 {
00284   pre_render_callback_ = func;
00285 }
00286 
00287 void QtOgreRenderWindow::setPostRenderCallback( boost::function<void ()> func )
00288 {
00289   post_render_callback_ = func;
00290 }
00291 
00292 //------------------------------------------------------------------------------
00293 void QtOgreRenderWindow::paintEvent( QPaintEvent* e )
00294 {
00295   if( auto_render_ && render_window_ )
00296   {
00297     if( pre_render_callback_ )
00298     {
00299       pre_render_callback_();
00300     }
00301 
00302     if( ogre_root_->_fireFrameStarted() )
00303     {
00304 #if (OGRE_VERSION_MAJOR >= 1 && OGRE_VERSION_MINOR >= 6)
00305       ogre_root_->_fireFrameRenderingQueued();
00306 #endif
00307 
00308       render_window_->update();
00309 
00310       ogre_root_->_fireFrameEnded();
00311     }
00312 
00313     if ( post_render_callback_ )
00314     {
00315       post_render_callback_();
00316     }
00317   }
00318 }
00319 
00320 //------------------------------------------------------------------------------
00321 void QtOgreRenderWindow::resizeEvent( QResizeEvent* event )
00322 {
00323   RenderWidget::resizeEvent( event );
00324 
00325   if( render_window_ )
00326   {
00327     setCameraAspectRatio();
00328 
00329     if( auto_render_ )
00330     {
00331       update();
00332     }
00333   }
00334 }
00335 
00336 } // namespace rviz


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Thu Aug 27 2015 15:02:28