Main MRPT website > C++ reference
MRPT logo
CDisplayWindow3D.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2014, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 #ifndef CDisplayWindow3D_H
10 #define CDisplayWindow3D_H
11 
16 #include <mrpt/utils/CImage.h>
17 
18 /*---------------------------------------------------------------
19  Class
20  ---------------------------------------------------------------*/
21 namespace mrpt
22 {
23  namespace gui
24  {
25  using namespace mrpt::utils;
26 
27  class C3DWindowDialog;
28  class CMyGLCanvas_DisplayWindow3D;
29 
31 
32  /** A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
33  * This class always contains internally an instance of opengl::COpenGLScene, which
34  * the objects, viewports, etc. to be rendered.
35  *
36  * Images can be grabbed automatically to disk for easy creation of videos.
37  * See CDisplayWindow3D::grabImagesStart (and for creating videos, mrpt::vision::CVideoFileWriter).
38  *
39  * A short-cut for displaying 2D images (using the OpenGL rendering hardware) is available
40  * through \a setImageView() and \a setImageView_fast(). Internally, these methods call methods
41  * in the "main" viewport of the window (see \a COpenGLViewport).
42  *
43  * Since the 3D rendering is performed in a detached thread, especial care must be taken
44  * when updating the 3D scene to be rendered. The process involves an internal critical section
45  * and it must always consist of these steps:
46  *
47  * \code
48  * CDisplayWindow3D win("My window");
49  *
50  * // Adquire the scene:
51  * opengl::COpenGLScenePtr &ptrScene = win.get3DSceneAndLock();
52  *
53  * // Modify the scene:
54  * ptrScene->...
55  * // or replace by another scene:
56  * ptrScene = otherScene;
57  *
58  * // Unlock it, so the window can use it for redraw:
59  * win.unlockAccess3DScene();
60  *
61  * // Update window, if required
62  * win.forceRepaint();
63  * \endcode
64  *
65  * An alternative way of updating the scene is by creating, before locking the 3D window, a new object
66  * of class COpenGLScene, then locking the window only for replacing the smart pointer. This may be
67  * advantageous is generating the 3D scene takes a long time, since while the window
68  * is locked it will not be responsive to the user input or window redraw.
69  *
70  * The window can also display a set of 2D text messages overlapped to the 3D scene.
71  * See CDisplayWindow3D::addTextMessage
72  *
73  * For a list of supported events with the observer/observable pattern, see the discussion in mrpt::gui::CBaseGUIWindow.
74  * In addition to those events, this class introduces mrpt::gui::mrptEvent3DWindowGrabImageFile
75  *
76  *
77  * \sa The example /samples/display3D, the <a href="http://www.mrpt.org/Tutorial_3D_Scenes" > tutorial only</a>.
78  * \ingroup mrpt_gui_grp
79  */
81  {
82  // This must be added to any CObject derived class:
84 
85  protected:
86  friend class C3DWindowDialog;
87  friend class CMyGLCanvas_DisplayWindow3D;
88  /** Internal OpenGL object (see general discussion in about usage of this object)
89  */
90  opengl::COpenGLScenePtr m_3Dscene;
91 
92  /** Critical section for accesing m_3Dscene
93  */
94  synch::CCriticalSection m_csAccess3DScene;
95 
96  /** Throws an exception on initialization error
97  */
98  void createOpenGLContext();
99 
100  void_ptr_noncopy m_DisplayDeviceContext;
101  void_ptr_noncopy m_GLRenderingContext;
102 
103  std::string m_grab_imgs_prefix;
104  unsigned int m_grab_imgs_idx;
105 
106  bool m_is_capturing_imgs;
107  CImagePtr m_last_captured_img;
108  synch::CCriticalSection m_last_captured_img_cs;
109 
110  void doRender();
111 
112  mrpt::system::TTimeStamp m_lastFullScreen;
113 
114  double m_last_FPS; //!< \sa getRenderingFPS
115 
116  void internalSetMinMaxRange();
117 
118  public:
119  /** Constructor
120  */
122  const std::string &windowCaption = std::string(),
123  unsigned int initialWindowWidth = 400,
124  unsigned int initialWindowHeight = 300 );
125 
126  /** Class factory returning a smart pointer */
127  static CDisplayWindow3DPtr Create(
128  const std::string &windowCaption,
129  unsigned int initialWindowWidth = 400,
130  unsigned int initialWindowHeight = 300 );
131 
132  /** Destructor
133  */
134  virtual ~CDisplayWindow3D();
135 
136  /** Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introduction in gui::CDisplayWindow3D before use!)
137  * This also locks the critical section for accesing the scene, thus the window will not be repainted until it is unlocked.
138  */
139  opengl::COpenGLScenePtr & get3DSceneAndLock( );
140 
141  /** Unlocks the access to the internal 3D scene.
142  * Typically user will want to call forceRepaint after updating the scene.
143  */
144  void unlockAccess3DScene();
145 
146  /** Repaints the window.
147  * forceRepaint, repaint and updateWindow are all aliases of the same method.
148  */
149  void forceRepaint();
150 
151  /** Repaints the window.
152  * forceRepaint, repaint and updateWindow are all aliases of the same method.
153  */
154  void repaint() { forceRepaint(); }
155 
156  /** Repaints the window.
157  * forceRepaint, repaint and updateWindow are all aliases of the same method.
158  */
159  void updateWindow() { forceRepaint(); }
160 
161  /** Return the camera field of view (in degrees) (used for gluPerspective). */
162  float getFOV() const;
163 
164  /** Changes the camera min clip range (z) (used for gluPerspective).
165  * The window is not updated with this method, call "forceRepaint" to update the 3D view.
166  */
167  void setMinRange(double new_min);
168 
169  /** Changes the camera max clip range (z) (used for gluPerspective).
170  * The window is not updated with this method, call "forceRepaint" to update the 3D view.
171  */
172  void setMaxRange(double new_max);
173 
174  /** Changes the camera field of view (in degrees) (used for gluPerspective).
175  * The window is not updated with this method, call "forceRepaint" to update the 3D view.
176  */
177  void setFOV(float v);
178 
179  /** Resizes the window, stretching the image to fit into the display area.
180  */
181  void resize( unsigned int width, unsigned int height );
182 
183  /** Changes the position of the window on the screen.
184  */
185  void setPos( int x, int y );
186 
187  /** Changes the window title.
188  */
189  void setWindowTitle( const std::string &str );
190 
191  /** Changes the camera parameters programatically
192  */
193  void setCameraElevationDeg( float deg );
194 
195  /** Changes the camera parameters programatically
196  */
197  void setCameraAzimuthDeg( float deg );
198 
199  /** Changes the camera parameters programatically
200  */
201  void setCameraPointingToPoint( float x,float y, float z );
202 
203  /** Changes the camera parameters programatically
204  */
205  void setCameraZoom( float zoom );
206 
207  /** Sets the camera as projective, or orthogonal. */
208  void setCameraProjective( bool isProjective );
209 
210 
211  /** Get camera parameters programatically */
212  float getCameraElevationDeg() const;
213 
214  /** Get camera parameters programatically */
215  float getCameraAzimuthDeg() const;
216 
217  /** Get camera parameters programatically */
218  void getCameraPointingToPoint( float &x,float &y, float &z ) const;
219 
220  /** Get camera parameters programatically */
221  float getCameraZoom() const;
222 
223  /** Sets the camera as projective, or orthogonal. */
224  bool isCameraProjective() const;
225 
226  /** 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.
227  */
228  void useCameraFromScene(bool useIt = true);
229 
230  /** 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 */
231  bool getLastMousePositionRay(mrpt::math::TLine3D &ray) const;
232 
233  /** Gets the last x,y pixel coordinates of the mouse. \return False if the window is closed. \sa getLastMousePositionRay */
234  virtual bool getLastMousePosition(int &x, int &y) const;
235 
236  /** Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) \sa getLastMousePositionRay */
237  virtual void setCursorCross(bool cursorIsCross);
238 
239  /** Start to save rendered images to disk.
240  * Images will be saved independently as png files, depending on
241  * the template path passed to this method. For example:
242  *
243  * path_prefix: "./video_"
244  *
245  * Will generate "./video_000001.png", etc.
246  *
247  * If this feature is enabled, the window will emit events of the type mrpt::gui::mrptEvent3DWindowGrabImageFile() which you can subscribe to.
248  *
249  * \sa grabImagesStop
250  */
251  void grabImagesStart( const std::string &grab_imgs_prefix = std::string("video_") );
252 
253  /** Stops image grabbing started by grabImagesStart
254  * \sa grabImagesStart
255  */
256  void grabImagesStop();
257 
258  /** Enables the grabbing of CImage objects from screenshots of the window.
259  * \sa getLastWindowImage
260  */
261  void captureImagesStart();
262 
263  /** Stop image grabbing
264  * \sa captureImagesStart
265  */
266  void captureImagesStop();
267 
268  /** Retrieve the last captured image from the window.
269  * You MUST CALL FIRST captureImagesStart to enable image grabbing.
270  * \return false if there was no time yet for grabbing any image (then, the output image is undefined).
271  * \sa captureImagesStart, getLastWindowImagePtr
272  */
273  bool getLastWindowImage( mrpt::utils::CImage &out_img) const;
274 
275  /** Retrieve the last captured image from the window, as a smart pointer.
276  * This method is more efficient than getLastWindowImage since only a copy of the pointer is performed, while
277  * getLastWindowImage would copy the entire image.
278  *
279  * You MUST CALL FIRST captureImagesStart to enable image grabbing.
280  * \Note If there was no time yet for grabbing any image, an empty smart pointer will be returned.
281  * \sa captureImagesStart, getLastWindowImage
282  */
283  mrpt::utils::CImagePtr getLastWindowImagePtr() const;
284 
285  /** Increments by one the image counter and return the next image file name (Users normally don't want to call this method).
286  * \sa grabImagesStart
287  */
288  std::string grabImageGetNextFile();
289 
290  bool isCapturingImgs() const { return m_is_capturing_imgs; }
291 
292 
293  /** Add 2D text messages overlapped to the 3D rendered scene. The string will remain displayed in the 3D window
294  * until it's changed with subsequent calls to this same method, or all the texts are cleared with clearTextMessages().
295  *
296  * \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[.
297  * \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[.
298  * \param text The text string to display.
299  * \param color The text color. For example: TColorf(1.0,1.0,1.0)
300  * \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.
301  *
302  * You'll need to refresh the display manually with forceRepaint().
303  *
304  * \sa clearTextMessages
305  */
306  void addTextMessage(
307  const double x,
308  const double y,
309  const std::string &text,
310  const mrpt::utils::TColorf &color = mrpt::utils::TColorf(1.0,1.0,1.0),
311  const size_t unique_index = 0,
313  );
314 
315  /** \overload with more font parameters - refer to mrpt::opengl::gl_utils::glDrawText()
316  * Available fonts are enumerated at mrpt::opengl::gl_utils::glSetFont() */
317  void addTextMessage(
318  const double x_frac,
319  const double y_frac,
320  const std::string &text,
321  const mrpt::utils::TColorf &color,
322  const std::string &font_name,
323  const double font_size,
325  const size_t unique_index = 0,
326  const double font_spacing = 1.5,
327  const double font_kerning = 0.1,
328  const bool draw_shadow = false,
329  const mrpt::utils::TColorf &shadow_color = mrpt::utils::TColorf(0,0,0)
330  );
331 
332  /** Clear all text messages created with addTextMessage().
333  * You'll need to refresh the display manually with forceRepaint().
334  * \sa addTextMessage
335  */
336  void clearTextMessages();
337 
338  /** Get the average Frames Per Second (FPS) value from the last 250 rendering events */
339  double getRenderingFPS() const { return m_last_FPS; }
340 
341  /** A short cut for getting the "main" viewport of the scene object, it is equivalent to:
342  * \code
343  * mrpt::opengl::COpenGLScenePtr &scene = win3D.get3DSceneAndLock();
344  * viewport = scene->getViewport("main");
345  * win3D.unlockAccess3DScene();
346  * \endcode
347  */
348  mrpt::opengl::COpenGLViewportPtr getDefaultViewport();
349 
350  /** Set the "main" viewport into "image view"-mode, where an image is efficiently drawn (fitting the viewport area) using an OpenGL textured quad.
351  * Call this method with the new image to update the displayed image (but recall to first lock the parent openglscene's critical section, then do the update, then release the lock, and then issue a window repaint).
352  * Internally, the texture is drawn using a mrpt::opengl::CTexturedPlane
353  * The viewport can be reverted to behave like a normal viewport by calling setNormalMode()
354  * \sa setImageView_fast, COpenGLViewport
355  */
356  void setImageView(const mrpt::utils::CImage &img);
357 
358  /** Just like \a setImageView but moves the internal image memory instead of making a copy, so it's faster but empties the input image.
359  * \sa setImageView, COpenGLViewport
360  */
361  void setImageView_fast(mrpt::utils::CImage &img);
362 
363 
364  protected:
365  void internal_setRenderingFPS(double FPS); //!< Set the rendering FPS (users don't call this, the method is for internal MRPT objects only) \sa getRenderingFPS
366  void internal_emitGrabImageEvent(const std::string &fil); //!< called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
367 
368  }; // End of class def.
370 
371 
372  /** @name Events specific to CDisplayWindow3D
373  @{ */
374 
375  /** An event sent by a CDisplayWindow3D window when an image is saved after enabling this feature with CDisplayWindow3D::grabImagesStart()
376  *
377  * IMPORTANTE NOTICE: Event handlers in your observer class will be invoked from the wxWidgets internal MRPT thread,
378  * so all your code in the handler must be thread safe.
379  */
381  {
382  protected:
383  virtual void do_nothing() { } //!< Just to allow this class to be polymorphic
384  public:
386  CDisplayWindow3D *obj,
387  const std::string &_img_file
388  ) : source_object(obj), img_file(_img_file) { }
389 
391  const std::string &img_file; //!< The absolute path of the file that has been just saved.
392  }; // End of class def.
393 
394  /** @} */
395 
396 
397  } // End of namespace
398 } // End of namespace
399 
400 #endif
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
Definition: datetime.h:30
An event sent by a CDisplayWindow3D window when an image is saved after enabling this feature with CD...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:97
The basic event type for the observer-observable pattern in MRPT.
Definition: mrptEvent.h:34
STL namespace.
const std::string & img_file
The absolute path of the file that has been just saved.
TOpenGLFont
Existing fonts for 2D texts in mrpt::opengl methods.
Definition: opengl_fonts.h:26
TOpenGLFontStyle
Different style for vectorized font rendering.
Definition: opengl_fonts.h:37
#define DEFINE_MRPT_OBJECT(class_name)
This declaration must be inserted in all CObject classes definition, within the class declaration...
Definition: CObject.h:167
#define DEFINE_MRPT_OBJECT_POST_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_)
Definition: CObject.h:172
double getRenderingFPS() const
Get the average Frames Per Second (FPS) value from the last 250 rendering events. ...
#define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_)
Definition: CObject.h:171
mrptEvent3DWindowGrabImageFile(CDisplayWindow3D *obj, const std::string &_img_file)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
renders glyphs filled with antialiased outlines
Definition: opengl_fonts.h:40
A RGB color - floats in the range [0,1].
Definition: TColor.h:52
void updateWindow()
Repaints the window.
virtual void do_nothing()
Just to allow this class to be polymorphic.
The base class for GUI window classes.
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
3D line, represented by a base point and a director vector.



Page generated by Doxygen 1.8.8 for MRPT 1.2.2 SVN:Unversioned directory at Tue Oct 14 02:14:08 UTC 2014