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:16:28 UTC 2011 |