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 |