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