Main MRPT website > C++ reference
MRPT logo

CDisplayWindow3D.h

Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                   http://mrpt.sourceforge.net/                            |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef  CDisplayWindow3D_H
00029 #define  CDisplayWindow3D_H
00030 
00031 #include <mrpt/gui/CBaseGUIWindow.h>
00032 #include <mrpt/opengl.h>
00033 #include <mrpt/opengl/opengl_fonts.h>
00034 #include <mrpt/utils/CImage.h>
00035 
00036 /*---------------------------------------------------------------
00037         Class
00038   ---------------------------------------------------------------*/
00039 namespace mrpt
00040 {
00041         namespace gui
00042         {
00043                 using namespace mrpt::utils;
00044 
00045                 class C3DWindowDialog;
00046                 class CMyGLCanvas_DisplayWindow3D;
00047 
00048                 DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE(CDisplayWindow3D, mrpt::gui::CBaseGUIWindow, GUI_IMPEXP)
00049 
00050                 /** A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
00051                   *  This class always contains internally an instance of opengl::COpenGLScene, which
00052                   *   the objects, viewports, etc. to be rendered.
00053                   *
00054                   *  Images can be grabbed automatically to disk for easy creation of videos.
00055                   *  See CDisplayWindow3D::grabImagesStart  (and for creating videos, mrpt::utils::CVideoFileWriter).
00056                   *
00057                   *
00058                   *  Since the 3D rendering is performed in a detached thread, especial care must be taken
00059                   *   when updating the 3D scene to be rendered. The process involves an internal critical section
00060                   *   and it must always consist of these steps:
00061                   *
00062                   * \code
00063                   *   CDisplayWindow3D  win("My window");
00064                   *
00065                   *   // Adquire the scene:
00066                   *   opengl::COpenGLScenePtr &ptrScene = win.get3DSceneAndLock();
00067                   *
00068                   *   // Modify the scene:
00069                   *   ptrScene->...
00070                   *   // or replace by another scene:
00071                   *   ptrScene = otherScene;
00072                   *
00073                   *   // Unlock it, so the window can use it for redraw:
00074                   *   win.unlockAccess3DScene();
00075                   *
00076                   *   // Update window, if required
00077                   *   win.forceRepaint();
00078                   * \endcode
00079                   *
00080                   * An alternative way of updating the scene is by creating, before locking the 3D window, a new object
00081                   *  of class COpenGLScene, then locking the window only for replacing the smart pointer. This may be
00082                   *  advantageous is generating the 3D scene takes a long time, since while the window
00083                   *  is locked it will not be responsive to the user input or window redraw.
00084                   *
00085                   * The window can also display a set of 2D text messages overlapped to the 3D scene.
00086                   *  See CDisplayWindow3D::add2DTextMessage
00087                   *
00088                   *  For a list of supported events with the observer/observable pattern, see the discussion in mrpt::gui::CBaseGUIWindow.
00089                   *
00090                   *
00091                   * \sa  The example /samples/display3D, the <a href="http://www.mrpt.org/Tutorial_3D_Scenes" > tutorial only</a>.
00092                   */
00093                 class GUI_IMPEXP CDisplayWindow3D : public mrpt::gui::CBaseGUIWindow
00094                 {
00095                         // This must be added to any CObject derived class:
00096                         DEFINE_MRPT_OBJECT( CDisplayWindow3D )
00097 
00098                 protected:
00099                         friend class C3DWindowDialog;
00100                         friend class CMyGLCanvas_DisplayWindow3D;
00101 
00102 
00103                         float m_FOV;
00104 
00105 
00106                         /** Internal OpenGL object (see general discussion in about usage of this object)
00107                           */
00108                         opengl::COpenGLScenePtr                 m_3Dscene;
00109 
00110                         /** Critical section for accesing m_3Dscene
00111                           */
00112                         synch::CCriticalSection         m_csAccess3DScene;
00113 
00114                         /** Throws an exception on initialization error
00115                           */
00116                         void  createOpenGLContext();
00117 
00118                         void_ptr_noncopy        m_DisplayDeviceContext;
00119                         void_ptr_noncopy        m_GLRenderingContext;
00120 
00121                         std::string             m_grab_imgs_prefix;
00122                         unsigned int            m_grab_imgs_idx;
00123 
00124                         bool                            m_is_capturing_imgs;
00125                         CImagePtr               m_last_captured_img;
00126                         synch::CCriticalSection         m_last_captured_img_cs;
00127 
00128                         void  doRender();
00129 
00130                         mrpt::system::TTimeStamp        m_lastFullScreen;
00131 
00132                         double   m_last_FPS; //!< \sa getRenderingFPS
00133 
00134                         void internalSetMinMaxRange();
00135 
00136                 public:
00137                         /** Constructor
00138                          */
00139                         CDisplayWindow3D(
00140                                 const std::string       &windowCaption = std::string(),
00141                                 unsigned int            initialWindowWidth = 400,
00142                                 unsigned int            initialWindowHeight = 300 );
00143 
00144                         /** Class factory returning a smart pointer */
00145                         static CDisplayWindow3DPtr Create(
00146                                 const std::string       &windowCaption = std::string(),
00147                                 unsigned int            initialWindowWidth = 400,
00148                                 unsigned int            initialWindowHeight = 300 )
00149                         {
00150                                 return CDisplayWindow3DPtr(new CDisplayWindow3D(windowCaption,initialWindowWidth,initialWindowHeight));
00151                         }
00152 
00153                         /** Destructor
00154                          */
00155                         virtual ~CDisplayWindow3D();
00156 
00157                         /** Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introduction in gui::CDisplayWindow3D before use!)
00158                           *  This also locks the critical section for accesing the scene, thus the window will not be repainted until it is unlocked.
00159                           */
00160                         opengl::COpenGLScenePtr & get3DSceneAndLock( );
00161 
00162                         /** Unlocks the access to the internal 3D scene.
00163                           *  Typically user will want to call forceRepaint after updating the scene.
00164                           */
00165                         void  unlockAccess3DScene();
00166 
00167                         /** Repaints the window.
00168                           * forceRepaint, repaint and updateWindow are all aliases of the same method.
00169                           */
00170                         void  forceRepaint();
00171 
00172                         /** Repaints the window.
00173                           * forceRepaint, repaint and updateWindow are all aliases of the same method.
00174                           */
00175                         void  repaint() { forceRepaint(); }
00176 
00177                         /** Repaints the window.
00178                           * forceRepaint, repaint and updateWindow are all aliases of the same method.
00179                           */
00180                         void  updateWindow() { forceRepaint(); }
00181 
00182                         /** Return the camera field of view (in degrees) (used for gluPerspective).
00183                           */
00184                         float getFOV() const { return m_FOV; };
00185 
00186                         /** Changes the camera min range (z) (used for gluPerspective).
00187                           *  The window is not updated with this method, call "forceRepaint" to update the 3D view.
00188                           */
00189                         void setMinRange(float v);
00190 
00191                         /** Changes the camera max range (z) (used for gluPerspective).
00192                           *  The window is not updated with this method, call "forceRepaint" to update the 3D view.
00193                           */
00194                         void setMaxRange(float v);
00195 
00196                         /** Changes the camera field of view (in degrees) (used for gluPerspective).
00197                           *  The window is not updated with this method, call "forceRepaint" to update the 3D view.
00198                           */
00199                         void setFOV(float v)  { m_FOV=v; };
00200 
00201                         /** Resizes the window, stretching the image to fit into the display area.
00202                          */
00203                         void  resize( unsigned int width, unsigned int height );
00204 
00205                         /** Changes the position of the window on the screen.
00206                          */
00207                         void  setPos( int x, int y );
00208 
00209                         /** Changes the window title.
00210                           */
00211                         void  setWindowTitle( const std::string &str );
00212 
00213                         /** Changes the camera parameters programatically
00214                           */
00215                         void setCameraElevationDeg( float deg );
00216 
00217                         /** Changes the camera parameters programatically
00218                           */
00219                         void setCameraAzimuthDeg( float deg );
00220 
00221                         /** Changes the camera parameters programatically
00222                           */
00223                         void setCameraPointingToPoint( float x,float y, float z );
00224 
00225                         /** Changes the camera parameters programatically
00226                           */
00227                         void setCameraZoom( float zoom );
00228 
00229                         /** Sets the camera as projective, or orthogonal. */
00230                         void setCameraProjective( bool isProjective );
00231 
00232 
00233                         /** Get camera parameters programatically */
00234                         float getCameraElevationDeg() const;
00235 
00236                         /** Get camera parameters programatically  */
00237                         float getCameraAzimuthDeg() const;
00238 
00239                         /** Get camera parameters programatically  */
00240                         void getCameraPointingToPoint( float &x,float &y, float &z ) const;
00241 
00242                         /** Get camera parameters programatically */
00243                         float getCameraZoom() const;
00244 
00245                         /** Sets the camera as projective, or orthogonal. */
00246                         bool isCameraProjective() const;
00247 
00248                         /**  If set to true (default = false), the mouse-based scene navigation will be disabled and the camera position will be determined by the opengl viewports in the 3D scene.
00249                           */
00250                         void useCameraFromScene(bool useIt = true);
00251 
00252                         /** Gets the 3D ray for the direction line of the pixel where the mouse cursor is at. \return False if the window is closed. \sa getLastMousePosition */
00253                         bool getLastMousePositionRay(mrpt::math::TLine3D &ray) const;
00254 
00255                         /** Gets the last x,y pixel coordinates of the mouse. \return False if the window is closed. \sa getLastMousePositionRay */
00256                         virtual bool getLastMousePosition(int &x, int &y) const;
00257 
00258                         /** Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) \sa getLastMousePositionRay */
00259                         virtual void setCursorCross(bool cursorIsCross);
00260 
00261                         /** Start to save rendered images to disk.
00262                           *  Images will be saved independently as png files, depending on
00263                           *   the template path passed to this method. For example:
00264                           *
00265                           *  path_prefix: "./video_"
00266                           *
00267                           *  Will generate "./video_000001.png", etc.
00268                           *
00269                           *  \sa grabImagesStop
00270                           */
00271                         void grabImagesStart( const std::string &grab_imgs_prefix = std::string("video_") );
00272 
00273                         /** Stops image grabbing started by grabImagesStart
00274                           * \sa grabImagesStart
00275                           */
00276                         void grabImagesStop();
00277 
00278                         /** Enables the grabbing of CImage objects from screenshots of the window.
00279                           *  \sa getLastWindowImage
00280                           */
00281                         void captureImagesStart();
00282 
00283                         /** Stop image grabbing
00284                           * \sa captureImagesStart
00285                           */
00286                         void captureImagesStop();
00287 
00288                         /** Retrieve the last captured image from the window.
00289                           *  You MUST CALL FIRST captureImagesStart to enable image grabbing.
00290                           * \sa captureImagesStart, getLastWindowImagePtr
00291                           */
00292                         void getLastWindowImage( mrpt::utils::CImage &out_img) const;
00293 
00294                         /** Retrieve the last captured image from the window, as a smart pointer.
00295                           *  This method is more efficient than getLastWindowImage since only a copy of the pointer is performed, while
00296                           *   getLastWindowImage would copy the entire image.
00297                           *
00298                           *  You MUST CALL FIRST captureImagesStart to enable image grabbing.
00299                           * \sa captureImagesStart, getLastWindowImage
00300                           */
00301                         mrpt::utils::CImagePtr getLastWindowImagePtr() const;
00302 
00303                         /** Increments by one the image counter and return the next image file name (Users normally don't want to call this method).
00304                           * \sa grabImagesStart
00305                           */
00306                         std::string grabImageGetNextFile();
00307 
00308                         bool isCapturingImgs() const {  return m_is_capturing_imgs; }
00309 
00310 
00311                         /** Add 2D text messages overlapped to the 3D rendered scene. The string will remain displayed in the 3D window
00312                           *   until it's changed with subsequent calls to this same method, or all the texts are cleared with clearTextMessages().
00313                           *
00314                           *  \param x The X position, interpreted as absolute pixels from the left if X>=1, absolute pixels from the left if X<0 or as a width factor if in the range [0,1[.
00315                           *  \param y The Y position, interpreted as absolute pixels from the bottom if Y>=1, absolute pixels from the top if Y<0 or as a height factor if in the range [0,1[.
00316                           *  \param text The text string to display.
00317                           *  \param color The text color. For example: TColorf(1.0,1.0,1.0)
00318                           *  \param unique_index An "index" for this text message, so that subsequent calls with the same index will overwrite this text message instead of creating new ones.
00319                           *
00320                           *  You'll need to refresh the display manually with forceRepaint().
00321                           *
00322                           * \sa clearTextMessages
00323                           */
00324                         void addTextMessage(
00325                                 const double x,
00326                                 const double y,
00327                                 const std::string &text,
00328                                 const mrpt::utils::TColorf &color = mrpt::utils::TColorf(1.0,1.0,1.0),
00329                                 const size_t unique_index = 0,
00330                                 const TOpenGLFont font = MRPT_GLUT_BITMAP_TIMES_ROMAN_24
00331                                 );
00332 
00333                         /**  Clear all text messages created with addTextMessage().
00334                           *  You'll need to refresh the display manually with forceRepaint().
00335                           * \sa addTextMessage
00336                           */
00337                         void clearTextMessages();
00338 
00339                         /** Set the rendering FPS (users don't call this, the method is for internal MRPT objects only) \sa getRenderingFPS */
00340                         void setRenderingFPS(double FPS);
00341 
00342                         /** Get the average Frames Per Second (FPS) value from the last 250 rendering events */
00343                         double getRenderingFPS() const { return m_last_FPS; }
00344 
00345                 }; // End of class def.
00346         } // End of namespace
00347 } // End of namespace
00348 
00349 #endif



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:40:17 UTC 2011