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://www.mrpt.org/                                |
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                   *  In addition to those events, this class introduces mrpt::gui::mrptEvent3DWindowGrabImageFile
00090                   *
00091                   *
00092                   * \sa  The example /samples/display3D, the <a href="http://www.mrpt.org/Tutorial_3D_Scenes" > tutorial only</a>.
00093                   * \ingroup mrpt_gui_grp
00094                   */
00095                 class GUI_IMPEXP CDisplayWindow3D : public mrpt::gui::CBaseGUIWindow
00096                 {
00097                         // This must be added to any CObject derived class:
00098                         DEFINE_MRPT_OBJECT( CDisplayWindow3D )
00099 
00100                 protected:
00101                         friend class C3DWindowDialog;
00102                         friend class CMyGLCanvas_DisplayWindow3D;
00103 
00104 
00105                         float m_FOV;
00106 
00107 
00108                         /** Internal OpenGL object (see general discussion in about usage of this object)
00109                           */
00110                         opengl::COpenGLScenePtr                 m_3Dscene;
00111 
00112                         /** Critical section for accesing m_3Dscene
00113                           */
00114                         synch::CCriticalSection         m_csAccess3DScene;
00115 
00116                         /** Throws an exception on initialization error
00117                           */
00118                         void  createOpenGLContext();
00119 
00120                         void_ptr_noncopy        m_DisplayDeviceContext;
00121                         void_ptr_noncopy        m_GLRenderingContext;
00122 
00123                         std::string             m_grab_imgs_prefix;
00124                         unsigned int            m_grab_imgs_idx;
00125 
00126                         bool                            m_is_capturing_imgs;
00127                         CImagePtr               m_last_captured_img;
00128                         synch::CCriticalSection         m_last_captured_img_cs;
00129 
00130                         void  doRender();
00131 
00132                         mrpt::system::TTimeStamp        m_lastFullScreen;
00133 
00134                         double   m_last_FPS; //!< \sa getRenderingFPS
00135 
00136                         void internalSetMinMaxRange();
00137 
00138                 public:
00139                         /** Constructor
00140                          */
00141                         CDisplayWindow3D(
00142                                 const std::string       &windowCaption = std::string(),
00143                                 unsigned int            initialWindowWidth = 400,
00144                                 unsigned int            initialWindowHeight = 300 );
00145 
00146                         /** Class factory returning a smart pointer */
00147                         static CDisplayWindow3DPtr Create(
00148                                 const std::string       &windowCaption = std::string(),
00149                                 unsigned int            initialWindowWidth = 400,
00150                                 unsigned int            initialWindowHeight = 300 )
00151                         {
00152                                 return CDisplayWindow3DPtr(new CDisplayWindow3D(windowCaption,initialWindowWidth,initialWindowHeight));
00153                         }
00154 
00155                         /** Destructor
00156                          */
00157                         virtual ~CDisplayWindow3D();
00158 
00159                         /** Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introduction in gui::CDisplayWindow3D before use!)
00160                           *  This also locks the critical section for accesing the scene, thus the window will not be repainted until it is unlocked.
00161                           */
00162                         opengl::COpenGLScenePtr & get3DSceneAndLock( );
00163 
00164                         /** Unlocks the access to the internal 3D scene.
00165                           *  Typically user will want to call forceRepaint after updating the scene.
00166                           */
00167                         void  unlockAccess3DScene();
00168 
00169                         /** Repaints the window.
00170                           * forceRepaint, repaint and updateWindow are all aliases of the same method.
00171                           */
00172                         void  forceRepaint();
00173 
00174                         /** Repaints the window.
00175                           * forceRepaint, repaint and updateWindow are all aliases of the same method.
00176                           */
00177                         void  repaint() { forceRepaint(); }
00178 
00179                         /** Repaints the window.
00180                           * forceRepaint, repaint and updateWindow are all aliases of the same method.
00181                           */
00182                         void  updateWindow() { forceRepaint(); }
00183 
00184                         /** Return the camera field of view (in degrees) (used for gluPerspective).
00185                           */
00186                         float getFOV() const { return m_FOV; };
00187 
00188                         /** Changes the camera min range (z) (used for gluPerspective).
00189                           *  The window is not updated with this method, call "forceRepaint" to update the 3D view.
00190                           */
00191                         void setMinRange(float v);
00192 
00193                         /** Changes the camera max range (z) (used for gluPerspective).
00194                           *  The window is not updated with this method, call "forceRepaint" to update the 3D view.
00195                           */
00196                         void setMaxRange(float v);
00197 
00198                         /** Changes the camera field of view (in degrees) (used for gluPerspective).
00199                           *  The window is not updated with this method, call "forceRepaint" to update the 3D view.
00200                           */
00201                         void setFOV(float v)  { m_FOV=v; };
00202 
00203                         /** Resizes the window, stretching the image to fit into the display area.
00204                          */
00205                         void  resize( unsigned int width, unsigned int height );
00206 
00207                         /** Changes the position of the window on the screen.
00208                          */
00209                         void  setPos( int x, int y );
00210 
00211                         /** Changes the window title.
00212                           */
00213                         void  setWindowTitle( const std::string &str );
00214 
00215                         /** Changes the camera parameters programatically
00216                           */
00217                         void setCameraElevationDeg( float deg );
00218 
00219                         /** Changes the camera parameters programatically
00220                           */
00221                         void setCameraAzimuthDeg( float deg );
00222 
00223                         /** Changes the camera parameters programatically
00224                           */
00225                         void setCameraPointingToPoint( float x,float y, float z );
00226 
00227                         /** Changes the camera parameters programatically
00228                           */
00229                         void setCameraZoom( float zoom );
00230 
00231                         /** Sets the camera as projective, or orthogonal. */
00232                         void setCameraProjective( bool isProjective );
00233 
00234 
00235                         /** Get camera parameters programatically */
00236                         float getCameraElevationDeg() const;
00237 
00238                         /** Get camera parameters programatically  */
00239                         float getCameraAzimuthDeg() const;
00240 
00241                         /** Get camera parameters programatically  */
00242                         void getCameraPointingToPoint( float &x,float &y, float &z ) const;
00243 
00244                         /** Get camera parameters programatically */
00245                         float getCameraZoom() const;
00246 
00247                         /** Sets the camera as projective, or orthogonal. */
00248                         bool isCameraProjective() const;
00249 
00250                         /**  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.
00251                           */
00252                         void useCameraFromScene(bool useIt = true);
00253 
00254                         /** 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 */
00255                         bool getLastMousePositionRay(mrpt::math::TLine3D &ray) const;
00256 
00257                         /** Gets the last x,y pixel coordinates of the mouse. \return False if the window is closed. \sa getLastMousePositionRay */
00258                         virtual bool getLastMousePosition(int &x, int &y) const;
00259 
00260                         /** Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) \sa getLastMousePositionRay */
00261                         virtual void setCursorCross(bool cursorIsCross);
00262 
00263                         /** Start to save rendered images to disk.
00264                           *  Images will be saved independently as png files, depending on
00265                           *   the template path passed to this method. For example:
00266                           *
00267                           *  path_prefix: "./video_"
00268                           *
00269                           *  Will generate "./video_000001.png", etc.
00270                           *
00271                           *  If this feature is enabled, the window will emit events of the type mrpt::gui::mrptEvent3DWindowGrabImageFile() which you can subscribe to.
00272                           *
00273                           *  \sa grabImagesStop
00274                           */
00275                         void grabImagesStart( const std::string &grab_imgs_prefix = std::string("video_") );
00276 
00277                         /** Stops image grabbing started by grabImagesStart
00278                           * \sa grabImagesStart
00279                           */
00280                         void grabImagesStop();
00281 
00282                         /** Enables the grabbing of CImage objects from screenshots of the window.
00283                           *  \sa getLastWindowImage
00284                           */
00285                         void captureImagesStart();
00286 
00287                         /** Stop image grabbing
00288                           * \sa captureImagesStart
00289                           */
00290                         void captureImagesStop();
00291 
00292                         /** Retrieve the last captured image from the window.
00293                           *  You MUST CALL FIRST captureImagesStart to enable image grabbing.
00294                           * \sa captureImagesStart, getLastWindowImagePtr
00295                           */
00296                         void getLastWindowImage( mrpt::utils::CImage &out_img) const;
00297 
00298                         /** Retrieve the last captured image from the window, as a smart pointer.
00299                           *  This method is more efficient than getLastWindowImage since only a copy of the pointer is performed, while
00300                           *   getLastWindowImage would copy the entire image.
00301                           *
00302                           *  You MUST CALL FIRST captureImagesStart to enable image grabbing.
00303                           * \sa captureImagesStart, getLastWindowImage
00304                           */
00305                         mrpt::utils::CImagePtr getLastWindowImagePtr() const;
00306 
00307                         /** Increments by one the image counter and return the next image file name (Users normally don't want to call this method).
00308                           * \sa grabImagesStart
00309                           */
00310                         std::string grabImageGetNextFile();
00311 
00312                         bool isCapturingImgs() const {  return m_is_capturing_imgs; }
00313 
00314 
00315                         /** Add 2D text messages overlapped to the 3D rendered scene. The string will remain displayed in the 3D window
00316                           *   until it's changed with subsequent calls to this same method, or all the texts are cleared with clearTextMessages().
00317                           *
00318                           *  \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[.
00319                           *  \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[.
00320                           *  \param text The text string to display.
00321                           *  \param color The text color. For example: TColorf(1.0,1.0,1.0)
00322                           *  \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.
00323                           *
00324                           *  You'll need to refresh the display manually with forceRepaint().
00325                           *
00326                           * \sa clearTextMessages
00327                           */
00328                         void addTextMessage(
00329                                 const double x,
00330                                 const double y,
00331                                 const std::string &text,
00332                                 const mrpt::utils::TColorf &color = mrpt::utils::TColorf(1.0,1.0,1.0),
00333                                 const size_t unique_index = 0,
00334                                 const TOpenGLFont font = MRPT_GLUT_BITMAP_TIMES_ROMAN_24
00335                                 );
00336 
00337                         /// \overload with more font parameters - refer to mrpt::opengl::gl_utils::glDrawText()
00338                         void addTextMessage(
00339                                 const double x_frac,
00340                                 const double y_frac,
00341                                 const std::string &text,
00342                                 const mrpt::utils::TColorf &color,
00343                                 const std::string  &font_name,
00344                                 const double  font_size,
00345                                 const mrpt::opengl::TOpenGLFontStyle font_style = mrpt::opengl::NICE,
00346                                 const size_t  unique_index = 0,
00347                                 const double  font_spacing = 1.5,
00348                                 const double  font_kerning = 0.1
00349                                 );
00350 
00351                         /**  Clear all text messages created with addTextMessage().
00352                           *  You'll need to refresh the display manually with forceRepaint().
00353                           * \sa addTextMessage
00354                           */
00355                         void clearTextMessages();
00356 
00357                         /** Get the average Frames Per Second (FPS) value from the last 250 rendering events */
00358                         double getRenderingFPS() const { return m_last_FPS; }
00359 
00360                 protected:
00361                         void internal_setRenderingFPS(double FPS);  //!< Set the rendering FPS (users don't call this, the method is for internal MRPT objects only) \sa getRenderingFPS
00362                         void internal_emitGrabImageEvent(const std::string &fil); //!< called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
00363 
00364                 }; // End of class def.
00365 
00366 
00367                 /** @name Events specific to CDisplayWindow3D
00368                         @{  */
00369 
00370                 /**  An event sent by a CDisplayWindow3D window when an image is saved after enabling this feature with CDisplayWindow3D::grabImagesStart()
00371                   *
00372                   *  IMPORTANTE NOTICE: Event handlers in your observer class will be invoked from the wxWidgets internal MRPT thread,
00373                   *    so all your code in the handler must be thread safe.
00374                   */
00375                 class GUI_IMPEXP mrptEvent3DWindowGrabImageFile : public mrptEvent
00376                 {
00377                 protected:
00378                         virtual void do_nothing() { } //!< Just to allow this class to be polymorphic
00379                 public:
00380                         inline mrptEvent3DWindowGrabImageFile(
00381                                 CDisplayWindow3D *obj,
00382                                 const std::string &_img_file
00383                                 ) : source_object(obj), img_file(_img_file) { }
00384 
00385                         CDisplayWindow3D  *source_object;
00386                         const std::string &img_file;    //!< The absolute path of the file that has been just saved.
00387                 }; // End of class def.
00388 
00389                 /** @} */
00390 
00391 
00392         } // End of namespace
00393 } // End of namespace
00394 
00395 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011