Main MRPT website > C++ reference for MRPT 1.5.7
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-2017, 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 namespace mrpt
19 {
20  namespace gui
21  {
22  class C3DWindowDialog;
23  class CMyGLCanvas_DisplayWindow3D;
24 
26 
27  /** A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
28  * This class always contains internally an instance of opengl::COpenGLScene, which
29  * the objects, viewports, etc. to be rendered.
30  *
31  * Images can be grabbed automatically to disk for easy creation of videos.
32  * See CDisplayWindow3D::grabImagesStart (and for creating videos, mrpt::vision::CVideoFileWriter).
33  *
34  * A short-cut for displaying 2D images (using the OpenGL rendering hardware) is available
35  * through \a setImageView() and \a setImageView_fast(). Internally, these methods call methods
36  * in the "main" viewport of the window (see \a COpenGLViewport).
37  *
38  * Since the 3D rendering is performed in a detached thread, especial care must be taken
39  * when updating the 3D scene to be rendered. The process involves an internal critical section
40  * and it must always consist of these steps:
41  *
42  * \code
43  * mrpt::gui::CDisplayWindow3D win("My window");
44  *
45  * // Adquire the scene:
46  * mrpt::opengl::COpenGLScenePtr &ptrScene = win.get3DSceneAndLock();
47  *
48  * // Modify the scene:
49  * ptrScene->...
50  * // or replace by another scene:
51  * ptrScene = otherScene;
52  *
53  * // Unlock it, so the window can use it for redraw:
54  * win.unlockAccess3DScene();
55  *
56  * // Update window, if required
57  * win.forceRepaint();
58  * \endcode
59  *
60  * An alternative way of updating the scene is by creating, before locking the 3D window, a new object
61  * of class COpenGLScene, then locking the window only for replacing the smart pointer. This may be
62  * advantageous is generating the 3D scene takes a long time, since while the window
63  * is locked it will not be responsive to the user input or window redraw.
64  *
65  * It is safer against exceptions to use the auxiliary class CDisplayWindow3DLocker.
66  * \code
67  * mrpt::gui::CDisplayWindow3D win("My window");
68  * // ...
69  * { // The scene is adquired in this scope
70  * mrpt::opengl::COpenGLScenePtr ptrScene;
71  * mrpt::gui::CDisplayWindow3DLocker locker(win,ptrScene);
72  * //...
73  *
74  * } // scene is unlocked upon dtor of `locker`
75  * \endcode
76  *
77  * Notice however that a copy of the smart pointer is made, so replacement of the entire scene
78  * via `operator =` is not possible if using this method. Still, in general it should be preferred because
79  * the mutexes are automatically released in case of unexpected exceptions.
80  *
81  * The window can also display a set of 2D text messages overlapped to the 3D scene.
82  * See CDisplayWindow3D::addTextMessage
83  *
84  * For a list of supported events with the observer/observable pattern, see the discussion in mrpt::gui::CBaseGUIWindow.
85  * In addition to those events, this class introduces mrpt::gui::mrptEvent3DWindowGrabImageFile
86  *
87  * ** CDisplayWindow3D mouse view navigation cheatsheet **
88  * - <b>Orbit camera</b>: Left-button pressed + move
89  * - <b>Zoom in / out</b>:
90  * - Mouse scroll wheel, or
91  * - SHIFT+Left-button pressed + move up/down
92  * - <b>Look around (pivot camera)</b>: CTRL+Left-button pressed + move up/down
93  * - <b>Pan (XY plane)</b>: Right-button pressed + move
94  * - <b>Move camera along Z axis</b>: SHIFT+Left-button pressed + move left/right
95  *
96  * \sa The example /samples/display3D, the <a href="http://www.mrpt.org/Tutorial_3D_Scenes" > tutorial only</a>.
97  * \ingroup mrpt_gui_grp
98  */
100  {
101  // This must be added to any CObject derived class:
103 
104  protected:
105  friend class C3DWindowDialog;
106  friend class CMyGLCanvas_DisplayWindow3D;
107 
108  mrpt::opengl::COpenGLScenePtr m_3Dscene; //!< Internal OpenGL object (see general discussion in about usage of this object)
109  mrpt::synch::CCriticalSectionRecursive m_csAccess3DScene; //!< Critical section for accesing m_3Dscene
110 
111  void createOpenGLContext(); //!< Throws an exception on initialization error
112 
115 
117  unsigned int m_grab_imgs_idx;
118 
120  mrpt::utils::CImagePtr m_last_captured_img;
122 
123  void doRender();
124 
126 
127  double m_last_FPS; //!< \sa getRenderingFPS
128 
129  void internalSetMinMaxRange();
130 
131  public:
132  /** Constructor */
134  const std::string &windowCaption = std::string(),
135  unsigned int initialWindowWidth = 400,
136  unsigned int initialWindowHeight = 300 );
137 
138  /** Class factory returning a smart pointer */
139  static CDisplayWindow3DPtr Create(
140  const std::string &windowCaption,
141  unsigned int initialWindowWidth = 400,
142  unsigned int initialWindowHeight = 300 );
143 
144  /** Destructor */
145  virtual ~CDisplayWindow3D();
146 
147  /** Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introduction in gui::CDisplayWindow3D before use!)
148  * This also locks the critical section for accesing the scene, thus the window will not be repainted until it is unlocked.
149  * \note It is safer to use mrpt::gui::CDisplayWindow3DLocker instead.*/
150  mrpt::opengl::COpenGLScenePtr & get3DSceneAndLock( );
151 
152  /** Unlocks the access to the internal 3D scene. It is safer to use mrpt::gui::CDisplayWindow3DLocker instead.
153  * Typically user will want to call forceRepaint after updating the scene. */
154  void unlockAccess3DScene();
155 
156  void forceRepaint(); //!< Repaints the window. forceRepaint, repaint and updateWindow are all aliases of the same method
157  void repaint() //!< Repaints the window. forceRepaint, repaint and updateWindow are all aliases of the same method
158  { forceRepaint(); }
159  void updateWindow() //!< Repaints the window. forceRepaint, repaint and updateWindow are all aliases of the same method
160  { forceRepaint(); }
161 
162  float getFOV() const; //!< Return the camera field of view (in degrees) (used for gluPerspective)
163  void setMinRange(double new_min);//!< Changes the camera min clip range (z) (used for gluPerspective). The window is not updated with this method, call "forceRepaint" to update the 3D view.
164  void setMaxRange(double new_max);//!< Changes the camera max clip range (z) (used for gluPerspective. The window is not updated with this method, call "forceRepaint" to update the 3D view.
165  void setFOV(float v);//!< Changes the camera field of view (in degrees) (used for gluPerspective). The window is not updated with this method, call "forceRepaint" to update the 3D view.
166  void resize( unsigned int width, unsigned int height) MRPT_OVERRIDE; //!< Resizes the window, stretching the image to fit into the display area.
167  void setPos( int x, int y ) MRPT_OVERRIDE;//!< Changes the position of the window on the screen.
168  void setWindowTitle( const std::string &str ) MRPT_OVERRIDE;//!< Changes the window title.
169  void setCameraElevationDeg( float deg );//!< Changes the camera parameters programmatically
170  void setCameraAzimuthDeg( float deg );//!< Changes the camera parameters programmatically
171  void setCameraPointingToPoint( float x,float y, float z );//!< Changes the camera parameters programmatically
172  void setCameraZoom( float zoom );//!< Changes the camera parameters programmatically
173  void setCameraProjective( bool isProjective );//!< Sets the camera as projective, or orthogonal.
174  float getCameraElevationDeg() const;//!< Get camera parameters programmatically
175  float getCameraAzimuthDeg() const;//!< Get camera parameters programmatically
176  void getCameraPointingToPoint( float &x,float &y, float &z ) const;//!< Get camera parameters programmatically
177  float getCameraZoom() const;//!< Get camera parameters programmatically
178  bool isCameraProjective() const;//!< Sets the camera as projective, or orthogonal
179  void useCameraFromScene(bool useIt = true);//!< 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
180  bool getLastMousePositionRay(mrpt::math::TLine3D &ray) const;//!< 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
181  virtual bool getLastMousePosition(int &x, int &y) const MRPT_OVERRIDE;//!< Gets the last x,y pixel coordinates of the mouse. \return False if the window is closed. \sa getLastMousePositionRay
182  virtual void setCursorCross(bool cursorIsCross) MRPT_OVERRIDE;//!< Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) \sa getLastMousePositionRay
183 
184  /** Start to save rendered images to disk.
185  * Images will be saved independently as png files, depending on
186  * the template path passed to this method. For example:
187  *
188  * path_prefix: "./video_"
189  *
190  * Will generate "./video_000001.png", etc.
191  *
192  * If this feature is enabled, the window will emit events of the type mrpt::gui::mrptEvent3DWindowGrabImageFile() which you can subscribe to.
193  *
194  * \sa grabImagesStop
195  */
196  void grabImagesStart( const std::string &grab_imgs_prefix = std::string("video_") );
197 
198  /** Stops image grabbing started by grabImagesStart
199  * \sa grabImagesStart
200  */
201  void grabImagesStop();
202 
203  /** Enables the grabbing of CImage objects from screenshots of the window.
204  * \sa getLastWindowImage
205  */
206  void captureImagesStart();
207 
208  /** Stop image grabbing
209  * \sa captureImagesStart
210  */
211  void captureImagesStop();
212 
213  /** Retrieve the last captured image from the window.
214  * You MUST CALL FIRST captureImagesStart to enable image grabbing.
215  * \return false if there was no time yet for grabbing any image (then, the output image is undefined).
216  * \sa captureImagesStart, getLastWindowImagePtr
217  */
218  bool getLastWindowImage( mrpt::utils::CImage &out_img) const;
219 
220  /** Retrieve the last captured image from the window, as a smart pointer.
221  * This method is more efficient than getLastWindowImage since only a copy of the pointer is performed, while
222  * getLastWindowImage would copy the entire image.
223  *
224  * You MUST CALL FIRST captureImagesStart to enable image grabbing.
225  * \Note If there was no time yet for grabbing any image, an empty smart pointer will be returned.
226  * \sa captureImagesStart, getLastWindowImage
227  */
228  mrpt::utils::CImagePtr getLastWindowImagePtr() const;
229 
230  /** Increments by one the image counter and return the next image file name (Users normally don't want to call this method).
231  * \sa grabImagesStart
232  */
233  std::string grabImageGetNextFile();
234 
235  bool isCapturingImgs() const { return m_is_capturing_imgs; }
236 
237 
238  /** Add 2D text messages overlapped to the 3D rendered scene. The string will remain displayed in the 3D window
239  * until it's changed with subsequent calls to this same method, or all the texts are cleared with clearTextMessages().
240  *
241  * \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[.
242  * \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[.
243  * \param text The text string to display.
244  * \param color The text color. For example: TColorf(1.0,1.0,1.0)
245  * \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.
246  *
247  * You'll need to refresh the display manually with forceRepaint().
248  *
249  * \sa clearTextMessages
250  */
251  void addTextMessage(
252  const double x,
253  const double y,
254  const std::string &text,
255  const mrpt::utils::TColorf &color = mrpt::utils::TColorf(1.0,1.0,1.0),
256  const size_t unique_index = 0,
258  );
259 
260  /** overload with more font parameters - refer to mrpt::opengl::gl_utils::glDrawText()
261  * Available fonts are enumerated at mrpt::opengl::gl_utils::glSetFont() */
262  void addTextMessage(
263  const double x_frac,
264  const double y_frac,
265  const std::string &text,
267  const std::string &font_name,
268  const double font_size,
270  const size_t unique_index = 0,
271  const double font_spacing = 1.5,
272  const double font_kerning = 0.1,
273  const bool draw_shadow = false,
274  const mrpt::utils::TColorf &shadow_color = mrpt::utils::TColorf(0,0,0)
275  );
276 
277  /** Clear all text messages created with addTextMessage().
278  * You'll need to refresh the display manually with forceRepaint().
279  * \sa addTextMessage
280  */
281  void clearTextMessages();
282 
283  /** Get the average Frames Per Second (FPS) value from the last 250 rendering events */
284  double getRenderingFPS() const { return m_last_FPS; }
285 
286  /** A short cut for getting the "main" viewport of the scene object, it is equivalent to:
287  * \code
288  * mrpt::opengl::COpenGLScenePtr &scene = win3D.get3DSceneAndLock();
289  * viewport = scene->getViewport("main");
290  * win3D.unlockAccess3DScene();
291  * \endcode
292  */
293  mrpt::opengl::COpenGLViewportPtr getDefaultViewport();
294 
295  /** Set the "main" viewport into "image view"-mode, where an image is efficiently drawn (fitting the viewport area) using an OpenGL textured quad.
296  * 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).
297  * Internally, the texture is drawn using a mrpt::opengl::CTexturedPlane
298  * The viewport can be reverted to behave like a normal viewport by calling setNormalMode()
299  * \sa setImageView_fast, COpenGLViewport
300  * \note This method already locks/unlocks the 3D scene of the window, so the user must NOT call get3DSceneAndLock() / unlockAccess3DScene() before/after calling it.
301  */
302  void setImageView(const mrpt::utils::CImage &img);
303 
304  /** Just like \a setImageView but moves the internal image memory instead of making a copy, so it's faster but empties the input image.
305  * \sa setImageView, COpenGLViewport
306  * \note This method already locks/unlocks the 3D scene of the window, so the user must NOT call get3DSceneAndLock() / unlockAccess3DScene() before/after calling it.
307  */
308  void setImageView_fast(mrpt::utils::CImage &img);
309 
310 
311  protected:
312  void internal_setRenderingFPS(double FPS); //!< Set the rendering FPS (users don't call this, the method is for internal MRPT objects only) \sa getRenderingFPS
313  void internal_emitGrabImageEvent(const std::string &fil); //!< called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
314 
315  }; // End of class def.
317 
318 
319  /** @name Events specific to CDisplayWindow3D
320  @{ */
321 
322  /** An event sent by a CDisplayWindow3D window when an image is saved after enabling this feature with CDisplayWindow3D::grabImagesStart()
323  *
324  * IMPORTANTE NOTICE: Event handlers in your observer class will be invoked from the wxWidgets internal MRPT thread,
325  * so all your code in the handler must be thread safe.
326  */
327  class GUI_IMPEXP mrptEvent3DWindowGrabImageFile : public mrpt::utils::mrptEvent
328  {
329  protected:
330  virtual void do_nothing() MRPT_OVERRIDE { } //!< Just to allow this class to be polymorphic
331  public:
334  const std::string &_img_file
335  ) : source_object(obj), img_file(_img_file) { }
336 
338  const std::string &img_file; //!< The absolute path of the file that has been just saved.
339  }; // End of class def.
340 
341  /** @} */
342 
343  /** Auxiliary class for safely claiming the 3DScene of a mrpt::gui::CDisplayWindow3D.
344  * The mutex will be hold between ctor and dtor calls of objects of this class, safely releasing
345  * the lock upon exceptions. See example usage code in docs of mrpt::gui::CDisplayWindow3D
346  *
347  * \ingroup mrpt_gui_grp
348  * \note New in MRPT 1.5.0
349  */
351  {
352  public:
353  /** Acquires the lock of the 3D scene of the referenced window, and returns a copy of the smart pointer to it. */
354  CDisplayWindow3DLocker(CDisplayWindow3D &win, mrpt::opengl::COpenGLScenePtr &out_scene_ptr);
355  /** Acquires the lock of the 3D scene of the referenced window. Use this signature when the scene object is not required. */
358 
359  private:
361  };
362 
363  } // End of namespace
364 } // End of namespace
365 
366 #endif
Recursive mutex: allow recursive locks by the owner thread.
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
Definition: datetime.h:30
virtual void do_nothing() MRPT_OVERRIDE
Just to allow this class to be polymorphic.
mrpt::utils::CImagePtr m_last_captured_img
An event sent by a CDisplayWindow3D window when an image is saved after enabling this feature with CD...
Auxiliary class for safely claiming the 3DScene of a mrpt::gui::CDisplayWindow3D. ...
This class provides simple critical sections functionality.
mrpt::opengl::COpenGLScenePtr m_3Dscene
Internal OpenGL object (see general discussion in about usage of this object)
GLdouble GLdouble z
Definition: glext.h:3734
#define MRPT_OVERRIDE
C++11 "override" for virtuals:
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:101
GLsizei GLsizei GLuint * obj
Definition: glext.h:3902
mrpt::synch::CCriticalSectionRecursive m_csAccess3DScene
Critical section for accesing m_3Dscene.
GLenum GLsizei width
Definition: glext.h:3513
GLuint color
Definition: glext.h:7093
double getRenderingFPS() const
Get the average Frames Per Second (FPS) value from the last 250 rendering events. ...
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
GLint GLvoid * img
Definition: glext.h:3645
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:187
#define DEFINE_MRPT_OBJECT_POST_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_)
Definition: CObject.h:192
GLsizei const GLchar ** string
Definition: glext.h:3919
#define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_)
Definition: CObject.h:191
mrptEvent3DWindowGrabImageFile(CDisplayWindow3D *obj, const std::string &_img_file)
const GLdouble * v
Definition: glext.h:3603
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
mrpt::system::TTimeStamp m_lastFullScreen
mrpt::utils::void_ptr_noncopy m_GLRenderingContext
synch::CCriticalSection m_last_captured_img_cs
renders glyphs filled with antialiased outlines
Definition: opengl_fonts.h:40
A RGB color - floats in the range [0,1].
Definition: TColor.h:80
mrpt::utils::void_ptr_noncopy m_DisplayDeviceContext
GLenum GLint GLint y
Definition: glext.h:3516
GLenum GLint x
Definition: glext.h:3516
GLenum GLsizei GLsizei height
Definition: glext.h:3523
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.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019