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   if(!right_camera_->isCustomProjectionMatrixEnabled()) {
00210     right_camera_->synchroniseBaseSettingsWith(camera_);
00211     right_camera_->setFrustumOffset(-camera_->getFrustumOffset());
00212   }
00213   right_viewport_->setCamera(right_camera_);
00214 }
00215 
00216 Ogre::Viewport* QtOgreRenderWindow::getViewport () const
00217 {
00218   return viewport_;
00219 }
00220 
00221 void QtOgreRenderWindow::setCamera( Ogre::Camera* camera )
00222 {
00223   if (camera)
00224   {
00225     camera_ = camera;
00226     viewport_->setCamera( camera );
00227 
00228     setCameraAspectRatio();
00229 
00230     if (camera_ && rendering_stereo_ && !left_camera_)
00231     {
00232       left_camera_ = camera_->getSceneManager()->createCamera(camera_->getName() + "-left");
00233     }
00234     if (camera_ && rendering_stereo_ && !right_camera_)
00235     {
00236       right_camera_ = camera_->getSceneManager()->createCamera(camera_->getName() + "-right");
00237     }
00238 
00239     update();
00240   }
00241 }
00242 
00243 void QtOgreRenderWindow::setOverlaysEnabled( bool overlays_enabled )
00244 {
00245   overlays_enabled_ = overlays_enabled;
00246   viewport_->setOverlaysEnabled( overlays_enabled );
00247   if (right_viewport_)
00248   {
00249     right_viewport_->setOverlaysEnabled( overlays_enabled );
00250   }
00251 }
00252 
00253 void QtOgreRenderWindow::setBackgroundColor( Ogre::ColourValue background_color )
00254 {
00255   background_color_ = background_color;
00256   viewport_->setBackgroundColour( background_color );
00257   if (right_viewport_)
00258   {
00259     right_viewport_->setBackgroundColour( background_color );
00260   }
00261 }
00262 
00263 void QtOgreRenderWindow::setCameraAspectRatio()
00264 {
00265   if ( camera_ )
00266   {
00267     camera_->setAspectRatio( Ogre::Real( width() ) / Ogre::Real( height() ) );
00268     if (right_camera_ ) {
00269       right_camera_->setAspectRatio( Ogre::Real( width() ) / Ogre::Real( height() ) );
00270     }
00271 
00272     if ( camera_->getProjectionType() == Ogre::PT_ORTHOGRAPHIC )
00273     {
00274       Ogre::Matrix4 proj;
00275       buildScaledOrthoMatrix( proj,
00276                               -width() / ortho_scale_ / 2, width() / ortho_scale_ / 2,
00277                               -height() / ortho_scale_ / 2, height() / ortho_scale_ / 2,
00278                               camera_->getNearClipDistance(), camera_->getFarClipDistance() );
00279       camera_->setCustomProjectionMatrix(true, proj);
00280     }
00281   }
00282 }
00283 
00284 void QtOgreRenderWindow::setOrthoScale( float scale )
00285 {
00286   ortho_scale_ = scale;
00287 
00288   setCameraAspectRatio();
00289 }
00290 
00291 void QtOgreRenderWindow::setPreRenderCallback( boost::function<void ()> func )
00292 {
00293   pre_render_callback_ = func;
00294 }
00295 
00296 void QtOgreRenderWindow::setPostRenderCallback( boost::function<void ()> func )
00297 {
00298   post_render_callback_ = func;
00299 }
00300 
00301 //------------------------------------------------------------------------------
00302 void QtOgreRenderWindow::paintEvent( QPaintEvent* e )
00303 {
00304   if( auto_render_ && render_window_ )
00305   {
00306     if( pre_render_callback_ )
00307     {
00308       pre_render_callback_();
00309     }
00310 
00311     if( ogre_root_->_fireFrameStarted() )
00312     {
00313 #if (OGRE_VERSION_MAJOR >= 1 && OGRE_VERSION_MINOR >= 6)
00314       ogre_root_->_fireFrameRenderingQueued();
00315 #endif
00316 
00317       render_window_->update();
00318 
00319       ogre_root_->_fireFrameEnded();
00320     }
00321 
00322     if ( post_render_callback_ )
00323     {
00324       post_render_callback_();
00325     }
00326   }
00327 }
00328 
00329 //------------------------------------------------------------------------------
00330 void QtOgreRenderWindow::resizeEvent( QResizeEvent* event )
00331 {
00332   RenderWidget::resizeEvent( event );
00333 
00334   if( render_window_ )
00335   {
00336     setCameraAspectRatio();
00337 
00338     if( auto_render_ )
00339     {
00340       update();
00341     }
00342   }
00343 }
00344 
00345 } // namespace rviz


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Tue Oct 3 2017 03:19:31