MRPT  1.9.9
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-2018, 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 
15 #include <mrpt/img/CImage.h>
16 #include <mrpt/system/datetime.h>
17 
18 #include <mutex>
19 
20 namespace mrpt::gui
21 {
22 class C3DWindowDialog;
23 class CMyGLCanvas_DisplayWindow3D;
24 
25 /** A graphical user interface (GUI) for efficiently rendering 3D scenes in
26  * real-time.
27  * This class always contains internally an instance of opengl::COpenGLScene,
28  * 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,
33  * mrpt::vision::CVideoFileWriter).
34  *
35  * A short-cut for displaying 2D images (using the OpenGL rendering hardware)
36  * is available
37  * through \a setImageView() and \a setImageView_fast(). Internally, these
38  * methods call methods
39  * in the "main" viewport of the window (see \a COpenGLViewport).
40  *
41  * Since the 3D rendering is performed in a detached thread, especial care
42  * must be taken
43  * when updating the 3D scene to be rendered. The process involves an
44  * internal critical section
45  * and it must always consist of these steps:
46  *
47  * \code
48  * mrpt::gui::CDisplayWindow3D win("My window");
49  *
50  * // Adquire the scene:
51  * mrpt::opengl::COpenGLScene::Ptr &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
66  * 3D window, a new object
67  * of class COpenGLScene, then locking the window only for replacing the smart
68  * pointer. This may be
69  * advantageous is generating the 3D scene takes a long time, since while the
70  * window
71  * is locked it will not be responsive to the user input or window redraw.
72  *
73  * It is safer against exceptions to use the auxiliary class
74  * CDisplayWindow3DLocker.
75  * \code
76  * mrpt::gui::CDisplayWindow3D win("My window");
77  * // ...
78  * { // The scene is adquired in this scope
79  * mrpt::opengl::COpenGLScene::Ptr ptrScene;
80  * mrpt::gui::CDisplayWindow3DLocker locker(win,ptrScene);
81  * //...
82  *
83  * } // scene is unlocked upon dtor of `locker`
84  * \endcode
85  *
86  * Notice however that a copy of the smart pointer is made, so replacement of
87  * the entire scene
88  * via `operator =` is not possible if using this method. Still, in general it
89  * should be preferred because
90  * the mutexes are automatically released in case of unexpected exceptions.
91  *
92  * The window can also display a set of 2D text messages overlapped to the 3D
93  * scene.
94  * See CDisplayWindow3D::addTextMessage
95  *
96  * For a list of supported events with the observer/observable pattern, see
97  * the discussion in mrpt::gui::CBaseGUIWindow.
98  * In addition to those events, this class introduces
99  * mrpt::gui::mrptEvent3DWindowGrabImageFile
100  *
101  * ** CDisplayWindow3D mouse view navigation cheatsheet **
102  * - <b>Orbit camera</b>: Left-button pressed + move
103  * - <b>Zoom in / out</b>:
104  * - Mouse scroll wheel, or
105  * - SHIFT+Left-button pressed + move up/down
106  * - <b>Look around (pivot camera)</b>: CTRL+Left-button pressed + move
107  * up/down
108  * - <b>Pan (XY plane)</b>: Right-button pressed + move
109  * - <b>Move camera along Z axis</b>: SHIFT+Left-button pressed + move
110  * left/right
111  *
112  * \sa The example /samples/display3D, the <a
113  * href="http://www.mrpt.org/Tutorial_3D_Scenes" > tutorial only</a>.
114  * \ingroup mrpt_gui_grp
115  */
117 {
118  public:
121 
122  protected:
123  friend class C3DWindowDialog;
125 
126  /** Internal OpenGL object (see general discussion in about usage of this
127  * object) */
129  /** Critical section for accesing m_3Dscene */
130  mutable std::recursive_mutex m_csAccess3DScene;
131 
132  /** Throws an exception on initialization error */
133  void createOpenGLContext();
134 
137 
139  unsigned int m_grab_imgs_idx;
140 
143  mutable std::mutex m_last_captured_img_cs;
144 
145  void doRender();
146 
148 
149  /** \sa getRenderingFPS */
150  double m_last_FPS;
151 
152  void internalSetMinMaxRange();
153 
154  public:
155  /** Constructor */
157  const std::string& windowCaption = std::string(),
158  unsigned int initialWindowWidth = 400,
159  unsigned int initialWindowHeight = 300);
160 
161  /** Class factory returning a smart pointer */
163  const std::string& windowCaption, unsigned int initialWindowWidth = 400,
164  unsigned int initialWindowHeight = 300);
165 
166  /** Destructor */
167  virtual ~CDisplayWindow3D();
168 
169  /** Gets a reference to the smart shared pointer that holds the internal
170  * scene (carefuly read introduction in gui::CDisplayWindow3D before use!)
171  * This also locks the critical section for accesing the scene, thus the
172  * window will not be repainted until it is unlocked.
173  * \note It is safer to use mrpt::gui::CDisplayWindow3DLocker instead.*/
175 
176  /** Unlocks the access to the internal 3D scene. It is safer to use
177  * mrpt::gui::CDisplayWindow3DLocker instead.
178  * Typically user will want to call forceRepaint after updating the scene.
179  */
180  void unlockAccess3DScene();
181 
182  /** Repaints the window. forceRepaint, repaint and updateWindow are all
183  * aliases of the same method */
184  void forceRepaint();
185  /** Repaints the window. forceRepaint, repaint and updateWindow are all
186  * aliases of the same method */
187  void repaint() { forceRepaint(); }
188  /** Repaints the window. forceRepaint, repaint and updateWindow are all
189  * aliases of the same method */
191  /** Return the camera field of view (in degrees) (used for gluPerspective)
192  */
193  float getFOV() const;
194  /** Changes the camera min clip range (z) (used for gluPerspective). The
195  * window is not updated with this method, call "forceRepaint" to update the
196  * 3D view. */
197  void setMinRange(double new_min);
198  /** Changes the camera max clip range (z) (used for gluPerspective. The
199  * window is not updated with this method, call "forceRepaint" to update the
200  * 3D view. */
201  void setMaxRange(double new_max);
202  /** Changes the camera field of view (in degrees) (used for gluPerspective).
203  * The window is not updated with this method, call "forceRepaint" to update
204  * the 3D view. */
205  void setFOV(float v);
206  /** Resizes the window, stretching the image to fit into the display area.
207  */
208  void resize(unsigned int width, unsigned int height) override;
209  /** Changes the position of the window on the screen. */
210  void setPos(int x, int y) override;
211  /** Changes the window title. */
212  void setWindowTitle(const std::string& str) override;
213  /** Changes the camera parameters programmatically */
214  void setCameraElevationDeg(float deg);
215  /** Changes the camera parameters programmatically */
216  void setCameraAzimuthDeg(float deg);
217  /** Changes the camera parameters programmatically */
218  void setCameraPointingToPoint(float x, float y, float z);
219  /** Changes the camera parameters programmatically */
220  void setCameraZoom(float zoom);
221  /** Sets the camera as projective, or orthogonal. */
222  void setCameraProjective(bool isProjective);
223  /** Get camera parameters programmatically */
224  float getCameraElevationDeg() const;
225  /** Get camera parameters programmatically */
226  float getCameraAzimuthDeg() const;
227  /** Get camera parameters programmatically */
228  void getCameraPointingToPoint(float& x, float& y, float& z) const;
229  /** Get camera parameters programmatically */
230  float getCameraZoom() const;
231  /** Sets the camera as projective, or orthogonal */
232  bool isCameraProjective() const;
233  /** If set to true (default = false), the mouse-based scene navigation will
234  * be disabled and the camera position will be determined by the opengl
235  * viewports in the 3D scene */
236  void useCameraFromScene(bool useIt = true);
237  /** Gets the 3D ray for the direction line of the pixel where the mouse
238  * cursor is at. \return False if the window is closed. \sa
239  * getLastMousePosition */
241  /** Gets the last x,y pixel coordinates of the mouse. \return False if the
242  * window is closed. \sa getLastMousePositionRay */
243  virtual bool getLastMousePosition(int& x, int& y) const override;
244  /** Set cursor style to default (cursorIsCross=false) or to a cross
245  * (cursorIsCross=true) \sa getLastMousePositionRay */
246  virtual void setCursorCross(bool cursorIsCross) override;
247 
248  /** Start to save rendered images to disk.
249  * Images will be saved independently as png files, depending on
250  * the template path passed to this method. For example:
251  *
252  * path_prefix: "./video_"
253  *
254  * Will generate "./video_000001.png", etc.
255  *
256  * If this feature is enabled, the window will emit events of the type
257  * mrpt::gui::mrptEvent3DWindowGrabImageFile() which you can subscribe to.
258  *
259  * \sa grabImagesStop
260  */
261  void grabImagesStart(
262  const std::string& grab_imgs_prefix = std::string("video_"));
263 
264  /** Stops image grabbing started by grabImagesStart
265  * \sa grabImagesStart
266  */
267  void grabImagesStop();
268 
269  /** Enables the grabbing of CImage objects from screenshots of the window.
270  * \sa getLastWindowImage
271  */
272  void captureImagesStart();
273 
274  /** Stop image grabbing
275  * \sa captureImagesStart
276  */
277  void captureImagesStop();
278 
279  /** Retrieve the last captured image from the window.
280  * You MUST CALL FIRST captureImagesStart to enable image grabbing.
281  * \return false if there was no time yet for grabbing any image (then, the
282  * output image is undefined).
283  * \sa captureImagesStart, getLastWindowImagePtr
284  */
285  bool getLastWindowImage(mrpt::img::CImage& out_img) const;
286 
287  /** Retrieve the last captured image from the window, as a smart pointer.
288  * This method is more efficient than getLastWindowImage since only a copy
289  * of the pointer is performed, while
290  * getLastWindowImage would copy the entire image.
291  *
292  * You MUST CALL FIRST captureImagesStart to enable image grabbing.
293  * \Note If there was no time yet for grabbing any image, an empty smart
294  * pointer will be returned.
295  * \sa captureImagesStart, getLastWindowImage
296  */
298 
299  /** Increments by one the image counter and return the next image file name
300  * (Users normally don't want to call this method).
301  * \sa grabImagesStart
302  */
304 
305  bool isCapturingImgs() const { return m_is_capturing_imgs; }
306  /** Add 2D text messages overlapped to the 3D rendered scene. The string
307  * will remain displayed in the 3D window
308  * until it's changed with subsequent calls to this same method, or all
309  * the texts are cleared with clearTextMessages().
310  *
311  * \param x The X position, interpreted as absolute pixels from the left
312  * if X>=1, absolute pixels from the left if X<0 or as a width factor if in
313  * the range [0,1[.
314  * \param y The Y position, interpreted as absolute pixels from the bottom
315  * if Y>=1, absolute pixels from the top if Y<0 or as a height factor if in
316  * the range [0,1[.
317  * \param text The text string to display.
318  * \param color The text color. For example: TColorf(1.0,1.0,1.0)
319  * \param unique_index An "index" for this text message, so that
320  * subsequent calls with the same index will overwrite this text message
321  * instead of creating new ones.
322  *
323  * You'll need to refresh the display manually with forceRepaint().
324  *
325  * \sa clearTextMessages
326  */
327  void addTextMessage(
328  const double x, const double y, const std::string& text,
329  const mrpt::img::TColorf& color = mrpt::img::TColorf(1.0, 1.0, 1.0),
330  const size_t unique_index = 0,
331  const mrpt::opengl::TOpenGLFont font =
333 
334  /** overload with more font parameters - refer to
335  * mrpt::opengl::gl_utils::glDrawText()
336  * Available fonts are enumerated at mrpt::opengl::gl_utils::glSetFont() */
337  void addTextMessage(
338  const double x_frac, const double y_frac, const std::string& text,
339  const mrpt::img::TColorf& color, const std::string& font_name,
340  const double font_size,
342  const size_t unique_index = 0, const double font_spacing = 1.5,
343  const double font_kerning = 0.1, const bool draw_shadow = false,
344  const mrpt::img::TColorf& shadow_color = mrpt::img::TColorf(0, 0, 0));
345 
346  /** Clear all text messages created with addTextMessage().
347  * You'll need to refresh the display manually with forceRepaint().
348  * \sa addTextMessage
349  */
350  void clearTextMessages();
351 
352  /** Get the average Frames Per Second (FPS) value from the last 250
353  * rendering events */
354  double getRenderingFPS() const { return m_last_FPS; }
355  /** A short cut for getting the "main" viewport of the scene object, it is
356  * equivalent to:
357  * \code
358  * mrpt::opengl::COpenGLScene::Ptr &scene = win3D.get3DSceneAndLock();
359  * viewport = scene->getViewport("main");
360  * win3D.unlockAccess3DScene();
361  * \endcode
362  */
364 
365  /** Set the "main" viewport into "image view"-mode, where an image is
366  * efficiently drawn (fitting the viewport area) using an OpenGL textured
367  * quad.
368  * Call this method with the new image to update the displayed image (but
369  * recall to first lock the parent openglscene's critical section, then do
370  * the update, then release the lock, and then issue a window repaint).
371  * Internally, the texture is drawn using a mrpt::opengl::CTexturedPlane
372  * The viewport can be reverted to behave like a normal viewport by
373  * calling setNormalMode()
374  * \sa setImageView_fast, COpenGLViewport
375  * \note This method already locks/unlocks the 3D scene of the window, so
376  * the user must NOT call get3DSceneAndLock() / unlockAccess3DScene()
377  * before/after calling it.
378  */
379  void setImageView(const mrpt::img::CImage& img);
380 
381  /** Just like \a setImageView but moves the internal image memory instead of
382  * making a copy, so it's faster but empties the input image.
383  * \sa setImageView, COpenGLViewport
384  * \note This method already locks/unlocks the 3D scene of the window, so
385  * the user must NOT call get3DSceneAndLock() / unlockAccess3DScene()
386  * before/after calling it.
387  */
389 
390  protected:
391  /** Set the rendering FPS (users don't call this, the method is for internal
392  * MRPT objects only) \sa getRenderingFPS */
393  void internal_setRenderingFPS(double FPS);
394  /** called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers */
395  void internal_emitGrabImageEvent(const std::string& fil);
396 
397 }; // End of class def.
398 
399 /** @name Events specific to CDisplayWindow3D
400  @{ */
401 
402 /** An event sent by a CDisplayWindow3D window when an image is saved after
403  * enabling this feature with CDisplayWindow3D::grabImagesStart()
404  *
405  * IMPORTANTE NOTICE: Event handlers in your observer class will be invoked
406  * from the wxWidgets internal MRPT thread,
407  * so all your code in the handler must be thread safe.
408  */
410 {
411  protected:
412  /** Just to allow this class to be polymorphic */
413  virtual void do_nothing() override {}
414  public:
416  CDisplayWindow3D* obj, const std::string& _img_file)
417  : source_object(obj), img_file(_img_file)
418  {
419  }
420 
422  /** The absolute path of the file that has been just saved. */
424 }; // End of class def.
425 
426 /** @} */
427 
428 /** Auxiliary class for safely claiming the 3DScene of a
429  * mrpt::gui::CDisplayWindow3D.
430  * The mutex will be hold between ctor and dtor calls of objects of this class,
431  * safely releasing
432  * the lock upon exceptions. See example usage code in docs of
433  * mrpt::gui::CDisplayWindow3D
434  *
435  * \ingroup mrpt_gui_grp
436  * \note New in MRPT 1.5.0
437  */
439 {
440  public:
441  /** Acquires the lock of the 3D scene of the referenced window, and returns
442  * a copy of the smart pointer to it. */
445  /** Acquires the lock of the 3D scene of the referenced window. Use this
446  * signature when the scene object is not required. */
449 
450  private:
452 };
453 
454 }
455 #endif
456 
457 
virtual bool getLastMousePosition(int &x, int &y) const override
Gets the last x,y pixel coordinates of the mouse.
virtual ~CDisplayWindow3D()
Destructor.
float getCameraAzimuthDeg() const
Get camera parameters programmatically.
bool getLastMousePositionRay(mrpt::math::TLine3D &ray) const
Gets the 3D ray for the direction line of the pixel where the mouse cursor is at. ...
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. ...
void unlockAccess3DScene()
Unlocks the access to the internal 3D scene.
std::recursive_mutex m_csAccess3DScene
Critical section for accesing m_3Dscene.
GLdouble GLdouble z
Definition: glext.h:3872
mrpt::img::CImage::Ptr getLastWindowImagePtr() const
Retrieve the last captured image from the window, as a smart pointer.
CDisplayWindow3DLocker(CDisplayWindow3D &win, mrpt::opengl::COpenGLScene::Ptr &out_scene_ptr)
Acquires the lock of the 3D scene of the referenced window, and returns a copy of the smart pointer t...
void setWindowTitle(const std::string &str) override
Changes the window title.
mrpt::opengl::COpenGLScene::Ptr & get3DSceneAndLock()
Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introductio...
void grabImagesStart(const std::string &grab_imgs_prefix=std::string("video_"))
Start to save rendered images to disk.
void resize(unsigned int width, unsigned int height) override
Resizes the window, stretching the image to fit into the display area.
The basic event type for the observer-observable pattern in MRPT.
Definition: mrptEvent.h:32
void setCameraPointingToPoint(float x, float y, float z)
Changes the camera parameters programmatically.
void createOpenGLContext()
Throws an exception on initialization error.
void setImageView_fast(mrpt::img::CImage &img)
Just like setImageView but moves the internal image memory instead of making a copy, so it&#39;s faster but empties the input image.
static CDisplayWindow3D::Ptr Create(const std::string &windowCaption, unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Class factory returning a smart pointer.
void internal_emitGrabImageEvent(const std::string &fil)
called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
void setCameraProjective(bool isProjective)
Sets the camera as projective, or orthogonal.
mrpt::void_ptr_noncopy m_GLRenderingContext
float getCameraZoom() const
Get camera parameters programmatically.
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
GLenum GLsizei width
Definition: glext.h:3531
friend class CMyGLCanvas_DisplayWindow3D
std::shared_ptr< CImage > Ptr
Definition: img/CImage.h:132
mrpt::opengl::COpenGLViewport::Ptr getDefaultViewport()
A short cut for getting the "main" viewport of the scene object, it is equivalent to: ...
GLuint color
Definition: glext.h:8300
double getRenderingFPS() const
Get the average Frames Per Second (FPS) value from the last 250 rendering events. ...
mrpt::Clock::time_point TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
Definition: datetime.h:40
mrpt::void_ptr_noncopy m_DisplayDeviceContext
const std::string & img_file
The absolute path of the file that has been just saved.
void getCameraPointingToPoint(float &x, float &y, float &z) const
Get camera parameters programmatically.
TOpenGLFont
Existing fonts for 2D texts in mrpt::opengl methods.
Definition: opengl_fonts.h:23
void setMaxRange(double new_max)
Changes the camera max clip range (z) (used for gluPerspective.
void setPos(int x, int y) override
Changes the position of the window on the screen.
std::string grabImageGetNextFile()
Increments by one the image counter and return the next image file name (Users normally don&#39;t want to...
GLint GLvoid * img
Definition: glext.h:3763
TOpenGLFontStyle
Different style for vectorized font rendering.
Definition: opengl_fonts.h:34
mrpt::gui::CDisplayWindow3D::Ptr win
GLsizei const GLchar ** string
Definition: glext.h:4101
void forceRepaint()
Repaints the window.
void setImageView(const mrpt::img::CImage &img)
Set the "main" viewport into "image view"-mode, where an image is efficiently drawn (fitting the view...
mrptEvent3DWindowGrabImageFile(CDisplayWindow3D *obj, const std::string &_img_file)
float getFOV() const
Return the camera field of view (in degrees) (used for gluPerspective)
const GLdouble * v
Definition: glext.h:3678
mrpt::system::TTimeStamp m_lastFullScreen
void grabImagesStop()
Stops image grabbing started by grabImagesStart.
A RGB color - floats in the range [0,1].
Definition: TColor.h:77
bool isCameraProjective() const
Sets the camera as projective, or orthogonal.
void setCameraZoom(float zoom)
Changes the camera parameters programmatically.
renders glyphs filled with antialiased outlines
Definition: opengl_fonts.h:38
void updateWindow()
Repaints the window.
virtual void setCursorCross(bool cursorIsCross) override
Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) ...
GLenum GLint GLint y
Definition: glext.h:3538
void setMinRange(double new_min)
Changes the camera min clip range (z) (used for gluPerspective).
bool getLastWindowImage(mrpt::img::CImage &out_img) const
Retrieve the last captured image from the window.
void addTextMessage(const double x, const double y, const std::string &text, const mrpt::img::TColorf &color=mrpt::img::TColorf(1.0, 1.0, 1.0), const size_t unique_index=0, const mrpt::opengl::TOpenGLFont font=mrpt::opengl::MRPT_GLUT_BITMAP_TIMES_ROMAN_24)
Add 2D text messages overlapped to the 3D rendered scene.
mrpt::img::CImage::Ptr m_last_captured_img
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:14
void captureImagesStop()
Stop image grabbing.
CDisplayWindow3D(const std::string &windowCaption=std::string(), unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Constructor.
GLenum GLint x
Definition: glext.h:3538
void repaint()
Repaints the window.
virtual void do_nothing() override
Just to allow this class to be polymorphic.
GLenum GLsizei GLsizei height
Definition: glext.h:3554
void internal_setRenderingFPS(double FPS)
Set the rendering FPS (users don&#39;t call this, the method is for internal MRPT objects only) ...
void clearTextMessages()
Clear all text messages created with addTextMessage().
mrpt::opengl::COpenGLScene::Ptr m_3Dscene
Internal OpenGL object (see general discussion in about usage of this object)
The base class for GUI window classes.
void setFOV(float v)
Changes the camera field of view (in degrees) (used for gluPerspective).
void setCameraAzimuthDeg(float deg)
Changes the camera parameters programmatically.
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:130
void setCameraElevationDeg(float deg)
Changes the camera parameters programmatically.
void useCameraFromScene(bool useIt=true)
If set to true (default = false), the mouse-based scene navigation will be disabled and the camera po...
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
void captureImagesStart()
Enables the grabbing of CImage objects from screenshots of the window.
3D line, represented by a base point and a director vector.
float getCameraElevationDeg() const
Get camera parameters programmatically.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020