Main MRPT website > C++ reference for MRPT 1.9.9
CDisplayWindow3D.cpp
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 
10 #include "gui-precomp.h" // Precompiled headers
11 
12 #include <mrpt/config.h>
13 
15 #include <mrpt/utils/CImage.h>
16 #include <mrpt/utils/CTicTac.h>
17 
18 #include <mrpt/gui/WxSubsystem.h>
19 #include <mrpt/gui/WxUtils.h>
20 
21 using namespace mrpt;
22 using namespace mrpt::gui;
23 using namespace mrpt::utils;
24 using namespace mrpt::system;
25 using namespace mrpt::opengl;
26 using namespace mrpt::math;
27 using namespace std;
28 
29 #if MRPT_HAS_OPENGL_GLUT
30 #ifdef MRPT_OS_WINDOWS
31 // Windows:
32 #include <windows.h>
33 #endif
34 
35 #ifdef MRPT_OS_APPLE
36 #include <OpenGL/gl.h>
37 #include <OpenGL/glu.h>
38 #include <GLUT/glut.h>
39 #else
40 #include <GL/gl.h>
41 #include <GL/glu.h>
42 #include <GL/glut.h>
43 #ifdef HAVE_FREEGLUT_EXT_H
44 #include <GL/freeglut_ext.h>
45 #endif
46 #endif
47 #endif
48 
49 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
50 
51 #if !wxUSE_GLCANVAS
52 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild wxWidgets"
53 #endif
54 
57 
58 namespace mrpt
59 {
60 namespace gui
61 {
62 class CMyGLCanvas_DisplayWindow3D : public mrpt::gui::CWxGLCanvasBase
63 {
64  public:
65  CMyGLCanvas_DisplayWindow3D(
66  CDisplayWindow3D* win3D, wxWindow* parent, wxWindowID id = wxID_ANY,
67  const wxPoint& pos = wxDefaultPosition,
68  const wxSize& size = wxDefaultSize, long style = 0,
69  const wxString& name = _T("CMyGLCanvas_DisplayWindow3D"));
70 
71  virtual ~CMyGLCanvas_DisplayWindow3D();
72 
73  CDisplayWindow3D* m_win3D = nullptr;
74 
75  // The idea is that CMyGLCanvas_DisplayWindow3D was derived from
76  // CTextMessageCapable, but
77  // that raises errors in MSVC when converting method pointers to
78  // wxObjectEventFunction...
79  struct THubClass : public mrpt::opengl::CTextMessageCapable
80  {
81  void render_text_messages_public(const int w, const int h) const
82  {
83  render_text_messages(w, h);
84  }
85  };
86  THubClass m_text_msgs;
87 
88  void OnCharCustom(wxKeyEvent& event);
89  void OnMouseDown(wxMouseEvent& event);
90  void OnMouseMove(wxMouseEvent& event);
91 
92  void OnPreRender();
93  void OnPostRender();
94  void OnPostRenderSwapBuffers(double At, wxPaintDC& dc);
95 
96  static void display3D_processKeyEvent(
97  CDisplayWindow3D* m_win3D, wxKeyEvent& ev);
98 };
99 }
100 }
101 
102 CMyGLCanvas_DisplayWindow3D::CMyGLCanvas_DisplayWindow3D(
103  CDisplayWindow3D* win3D, wxWindow* parent, wxWindowID id,
104  const wxPoint& pos, const wxSize& size, long style, const wxString& name)
105  : CWxGLCanvasBase(parent, id, pos, size, style, name), m_win3D(win3D)
106 {
107  this->Bind(wxEVT_CHAR, &CMyGLCanvas_DisplayWindow3D::OnCharCustom, this);
108  this->Bind(
109  wxEVT_CHAR_HOOK, &CMyGLCanvas_DisplayWindow3D::OnCharCustom, this);
110  this->Bind(
111  wxEVT_LEFT_DOWN, &CMyGLCanvas_DisplayWindow3D::OnMouseDown, this);
112  this->Bind(
113  wxEVT_RIGHT_DOWN, &CMyGLCanvas_DisplayWindow3D::OnMouseDown, this);
114  this->Bind(wxEVT_MOTION, &CMyGLCanvas_DisplayWindow3D::OnMouseMove, this);
115 }
116 
117 void CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(
118  CDisplayWindow3D* m_win3D, wxKeyEvent& ev)
119 {
120  if (m_win3D)
121  {
122  if (ev.AltDown() && ev.GetKeyCode() == MRPTK_RETURN)
123  {
125  m_win3D->m_lastFullScreen, mrpt::system::now()) > 0.2)
126  {
127  m_win3D->m_lastFullScreen = mrpt::system::now();
128  cout << "[CDisplayWindow3D] Switching fullscreen...\n";
129  C3DWindowDialog* win = (C3DWindowDialog*)m_win3D->m_hwnd.get();
130  if (win)
131  {
132  win->ShowFullScreen(!win->IsFullScreen());
133  }
134  }
135  // Alt+Enter: Don't notify on this key stroke, since if we're
136  // switching to fullscreen
137  // and the user is waiting for a key to close the window, a runtime
138  // crash will occur,
139  // so return now:
140  return;
141  }
142 
143  const int code = ev.GetKeyCode();
145 
146  m_win3D->m_keyPushedCode = code;
147  m_win3D->m_keyPushedModifier = mod;
148  m_win3D->m_keyPushed = true;
149 
150  // Send the event:
151  try
152  {
153  m_win3D->publishEvent(mrptEventWindowChar(m_win3D, code, mod));
154  }
155  catch (...)
156  {
157  }
158  }
159  // ev.Skip(); // Pass the event to whoever else.
160 }
161 
162 void CMyGLCanvas_DisplayWindow3D::OnCharCustom(wxKeyEvent& ev)
163 {
164  CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(m_win3D, ev);
165 }
166 
167 void CMyGLCanvas_DisplayWindow3D::OnMouseDown(wxMouseEvent& event)
168 {
169  // Send the event:
170  if (m_win3D && m_win3D->hasSubscribers())
171  {
172  try
173  {
174  m_win3D->publishEvent(
176  m_win3D, TPixelCoord(event.GetX(), event.GetY()),
177  event.LeftDown(), event.RightDown()));
178  }
179  catch (...)
180  {
181  }
182  }
183 
184  event.Skip(); // so it's processed by the wx system!
185 }
186 
187 void CMyGLCanvas_DisplayWindow3D::OnMouseMove(wxMouseEvent& event)
188 {
189  // Send the event:
190  if (m_win3D && m_win3D->hasSubscribers())
191  {
192  try
193  {
194  m_win3D->publishEvent(
196  m_win3D, TPixelCoord(event.GetX(), event.GetY()),
197  event.LeftDown(), event.RightDown()));
198  }
199  catch (...)
200  {
201  }
202  }
203 
204  event.Skip(); // so it's processed by the wx system!
205 }
206 
207 CMyGLCanvas_DisplayWindow3D::~CMyGLCanvas_DisplayWindow3D()
208 {
209  getOpenGLSceneRef().reset(); // Avoid the base class to free this object
210  // (it's freed by CDisplayWindow3D)
211 }
212 
213 void CMyGLCanvas_DisplayWindow3D::OnPreRender()
214 {
215  auto& openGLSceneRef = getOpenGLSceneRef();
216  if (openGLSceneRef) openGLSceneRef.reset();
217 
218  COpenGLScene::Ptr& ptrScene = m_win3D->get3DSceneAndLock();
219  if (ptrScene) openGLSceneRef = ptrScene;
220 }
221 
222 void CMyGLCanvas_DisplayWindow3D::OnPostRender()
223 {
224  // Avoid the base class to free this object (it's freed by CDisplayWindow3D)
225  getOpenGLSceneRef().reset();
226  m_win3D->unlockAccess3DScene();
227 
228  // If any, draw the 2D text messages:
229  int w, h;
230  this->GetSize(&w, &h);
231 
232  m_text_msgs.render_text_messages_public(w, h);
233 }
234 
235 void CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers(
236  double At, wxPaintDC& dc)
237 {
238  if (m_win3D) m_win3D->internal_setRenderingFPS(At > 0 ? 1.0 / At : 1e9);
239 
240  // If we are requested to do so, grab images to disk as they are rendered:
241  string grabFile;
242  if (m_win3D) grabFile = m_win3D->grabImageGetNextFile();
243  if (m_win3D && (!grabFile.empty() || m_win3D->isCapturingImgs()))
244  {
245  int w, h;
246  dc.GetSize(&w, &h);
247 
248  // Save image directly from OpenGL - It could also use 4 channels and
249  // save with GL_BGRA_EXT
250  CImage::Ptr frame(new CImage(w, h, 3, false));
252  glReadPixels(0, 0, w, h, GL_BGR_EXT, GL_UNSIGNED_BYTE, (*frame)(0, 0));
253 
254  if (!grabFile.empty())
255  {
256  frame->saveToFile(grabFile);
257  m_win3D->internal_emitGrabImageEvent(grabFile);
258  }
259 
260  if (m_win3D->isCapturingImgs())
261  {
262  {
263  std::lock_guard<std::mutex> lock(
264  m_win3D->m_last_captured_img_cs);
265  m_win3D->m_last_captured_img = frame;
266  frame.reset();
267  }
268  }
269  }
270 }
271 
272 #endif // Wx + OpenGL
273 
274 #if MRPT_HAS_WXWIDGETS
275 
276 BEGIN_EVENT_TABLE(C3DWindowDialog, wxFrame)
277 
278 END_EVENT_TABLE()
279 
280 const long C3DWindowDialog::ID_MENUITEM1 = wxNewId();
281 const long C3DWindowDialog::ID_MENUITEM2 = wxNewId();
282 
284  CDisplayWindow3D* win3D, WxSubsystem::CWXMainFrame* parent, wxWindowID id,
285  const std::string& caption, wxSize initialSize)
286  : m_win3D(win3D), m_mainFrame(parent)
287 {
288 #if MRPT_HAS_OPENGL_GLUT
289 
290  Create(
291  parent, id, _U(caption.c_str()), wxDefaultPosition, initialSize,
292  wxDEFAULT_FRAME_STYLE, _T("id"));
293 
294  wxIcon FrameIcon;
295  FrameIcon.CopyFromBitmap(mrpt::gui::WxSubsystem::getMRPTDefaultIcon());
296  SetIcon(FrameIcon);
297 
298  // Create the wxCanvas object:
299  m_canvas = new CMyGLCanvas_DisplayWindow3D(
300  win3D, this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
301 
302  // Events:
303  this->Bind(wxEVT_CLOSE_WINDOW, &C3DWindowDialog::OnClose, this);
304  this->Bind(
305  wxEVT_COMMAND_MENU_SELECTED, &C3DWindowDialog::OnMenuClose, this,
306  ID_MENUITEM1);
307  this->Bind(
308  wxEVT_COMMAND_MENU_SELECTED, &C3DWindowDialog::OnMenuAbout, this,
309  ID_MENUITEM2);
310  this->Bind(wxEVT_CHAR, &C3DWindowDialog::OnChar, this);
311  this->Bind(wxEVT_SIZE, &C3DWindowDialog::OnResize, this);
312 
313  // Increment number of windows:
314  // int winCount =
316 // cout << "[C3DWindowDialog] Notifying new window: " << winCount << endl;
317 #else
318  THROW_EXCEPTION("MRPT was compiled without OpenGL support")
319 #endif
320  // this->Iconize(false);
321 }
322 
323 // Destructor
325 {
326  // cout << "[C3DWindowDialog::~C3DWindowDialog]" << endl;
327 }
328 
329 // OnClose event:
330 void C3DWindowDialog::OnClose(wxCloseEvent& event)
331 {
332  // Send the event:
333  bool allow_close = true;
334  try
335  {
336  mrptEventWindowClosed ev(m_win3D, true /* allow close */);
337  m_win3D->publishEvent(ev);
338  allow_close = ev.allow_close;
339  }
340  catch (...)
341  {
342  }
343  if (!allow_close) return; // Don't process this close event.
344 
345  // cout << "[C3DWindowDialog::OnClose]" << endl;
346  // Set the m_hwnd=nullptr in our parent object.
348 
349  // Decrement number of windows:
351 
352  // Signal we are destroyed:
353  m_win3D->m_windowDestroyed.set_value();
354 
355  event.Skip(); // keep processing by parent classes.
356 }
357 
358 // Menu: Close
359 void C3DWindowDialog::OnMenuClose(wxCommandEvent& event) { Close(); }
360 // Menu: About
361 void C3DWindowDialog::OnMenuAbout(wxCommandEvent& event)
362 {
363  ::wxMessageBox(
364  _("3D Scene viewer\n Class gui::CDisplayWindow3D\n MRPT C++ library"),
365  _("About..."));
366 }
367 
368 void C3DWindowDialog::OnChar(wxKeyEvent& ev)
369 {
370 #if MRPT_HAS_OPENGL_GLUT
371  CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(m_win3D, ev);
372 #endif
373 }
374 
375 void C3DWindowDialog::OnResize(wxSizeEvent& event)
376 {
377 #if MRPT_HAS_OPENGL_GLUT
378  // Send the event:
379  if (m_win3D)
380  {
381  try
382  {
385  m_win3D, event.GetSize().GetWidth(),
386  event.GetSize().GetHeight()));
387  }
388  catch (...)
389  {
390  }
391  }
392  event.Skip(); // so it's processed by the wx system!
393 #endif
394 }
395 
397 {
398 #if MRPT_HAS_OPENGL_GLUT
399  m_canvas->m_text_msgs.clearTextMessages();
400 #endif
401 }
402 
404  const double x_frac, const double y_frac, const std::string& text,
405  const mrpt::utils::TColorf& color, const size_t unique_index,
406  const mrpt::opengl::TOpenGLFont font)
407 {
408 #if MRPT_HAS_OPENGL_GLUT
409  m_canvas->m_text_msgs.addTextMessage(
410  x_frac, y_frac, text, color, unique_index, font);
411 #endif
412 }
413 
415  const double x_frac, const double y_frac, const std::string& text,
416  const mrpt::utils::TColorf& color, const std::string& font_name,
417  const double font_size, const mrpt::opengl::TOpenGLFontStyle font_style,
418  const size_t unique_index, const double font_spacing,
419  const double font_kerning, const bool has_shadow,
420  const mrpt::utils::TColorf& shadow_color)
421 {
422 #if MRPT_HAS_OPENGL_GLUT
423  m_canvas->m_text_msgs.addTextMessage(
424  x_frac, y_frac, text, color, font_name, font_size, font_style,
425  unique_index, font_spacing, font_kerning, has_shadow, shadow_color);
426 #endif
427 }
428 
429 #endif // MRPT_HAS_WXWIDGETS
430 
431 /*---------------------------------------------------------------
432  Constructor
433  ---------------------------------------------------------------*/
435  const std::string& windowCaption, unsigned int initialWindowWidth,
436  unsigned int initialWindowHeight)
437  : CBaseGUIWindow(static_cast<void*>(this), 300, 399, windowCaption),
438  m_grab_imgs_prefix(),
439  m_grab_imgs_idx(0),
440  m_is_capturing_imgs(false),
441  m_lastFullScreen(mrpt::system::now()),
442  m_last_FPS(10)
443 {
444  // static mrpt::utils::CStdOutStream oo;
445  // m_csAccess3DScene.m_debugOut = &oo;
446 
447  m_3Dscene = COpenGLScene::Create();
448  CBaseGUIWindow::createWxWindow(initialWindowWidth, initialWindowHeight);
449 }
450 
452  const std::string& windowCaption, unsigned int initialWindowWidth,
453  unsigned int initialWindowHeight)
454 {
455  return CDisplayWindow3D::Ptr(
456  new CDisplayWindow3D(
457  windowCaption, initialWindowWidth, initialWindowHeight));
458 }
459 /*---------------------------------------------------------------
460  Destructor
461  ---------------------------------------------------------------*/
463 {
464  // get lock so we make sure nobody else is touching the window right now.
465  m_csAccess3DScene.lock();
466  m_csAccess3DScene.unlock();
467 
469 }
470 
471 /*---------------------------------------------------------------
472  resize
473  ---------------------------------------------------------------*/
474 void CDisplayWindow3D::resize(unsigned int width, unsigned int height)
475 {
476 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
477  if (!isOpen())
478  {
479  cerr << "[CDisplayWindow3D::setPos] Window closed!: " << m_caption
480  << endl;
481  return;
482  }
483 
484  // Send a request to destroy this object:
487  REQ->source3D = this;
488  REQ->OPCODE = 303;
489  REQ->x = width;
490  REQ->y = height;
492 #else
495 #endif
496 }
497 
498 /*---------------------------------------------------------------
499  setPos
500  ---------------------------------------------------------------*/
502 {
503 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
504  if (!isOpen())
505  {
506  cerr << "[CDisplayWindow3D::setPos] Window closed!: " << m_caption
507  << endl;
508  return;
509  }
510 
511  // Send a request to destroy this object:
514  REQ->source3D = this;
515  REQ->OPCODE = 302;
516  REQ->x = x;
517  REQ->y = y;
519 #else
522 #endif
523 }
524 
525 /*---------------------------------------------------------------
526  setWindowTitle
527  ---------------------------------------------------------------*/
529 {
530 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
531  if (!isOpen())
532  {
533  cerr << "[CDisplayWindow3D::setWindowTitle] Window closed!: "
534  << m_caption << endl;
535  return;
536  }
537 
538  // Send a request to destroy this object:
541  REQ->source3D = this;
542  REQ->OPCODE = 304;
543  REQ->str = str;
545 #else
546  MRPT_UNUSED_PARAM(str);
547 #endif
548 }
549 
550 /*---------------------------------------------------------------
551  get3DSceneAndLock
552  ---------------------------------------------------------------*/
554 {
555  m_csAccess3DScene.lock();
556  return m_3Dscene;
557 }
558 
559 /*---------------------------------------------------------------
560  unlockAccess3DScene
561  ---------------------------------------------------------------*/
563 /*---------------------------------------------------------------
564  forceRepaint
565  ---------------------------------------------------------------*/
567 {
568 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
570  if (win)
571  {
572  // win->Refresh(false); // Do not erase background
573  // We must do this from the wx thread!
574 
575  // Send refresh request:
578  REQ->source3D = this;
579  REQ->OPCODE = 350;
581  }
582 #endif
583 }
584 
585 /*---------------------------------------------------------------
586  setCameraElevationDeg
587  ---------------------------------------------------------------*/
589 {
590 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
592  if (win) win->m_canvas->setElevationDegrees(deg);
593 #else
594  MRPT_UNUSED_PARAM(deg);
595 #endif
596 }
597 
599 {
600 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
602  if (win) win->m_canvas->setUseCameraFromScene(useIt);
603 #else
604  MRPT_UNUSED_PARAM(useIt);
605 #endif
606 }
607 
608 /*---------------------------------------------------------------
609  setCameraAzimuthDeg
610  ---------------------------------------------------------------*/
612 {
613 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
615  if (win) win->m_canvas->setAzimuthDegrees(deg);
616 #else
617  MRPT_UNUSED_PARAM(deg);
618 #endif
619 }
620 
621 /*---------------------------------------------------------------
622  setCameraPointingToPoint
623  ---------------------------------------------------------------*/
625 {
626 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
628  if (win)
629  {
630  win->m_canvas->setCameraPointing(x, y, z);
631  }
632 #else
636 #endif
637 }
638 
639 /*---------------------------------------------------------------
640  setCameraZoom
641  ---------------------------------------------------------------*/
643 {
644 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
646  if (win) win->m_canvas->setZoomDistance(zoom);
647 #else
648  MRPT_UNUSED_PARAM(zoom);
649 #endif
650 }
651 
652 /*---------------------------------------------------------------
653  setCameraProjective
654  ---------------------------------------------------------------*/
656 {
657 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
659  if (win) win->m_canvas->setCameraProjective(isProjective);
660 #else
661  MRPT_UNUSED_PARAM(isProjective);
662 #endif
663 }
664 
665 void CDisplayWindow3D::setMinRange(double new_min)
666 {
667  if (m_3Dscene)
668  {
670  m_3Dscene->getViewport("main");
671  if (gl_view)
672  {
673  double m, M;
674  gl_view->getViewportClipDistances(m, M);
675  gl_view->setViewportClipDistances(new_min, M);
676  }
677  }
678 }
679 void CDisplayWindow3D::setMaxRange(double new_max)
680 {
681  if (m_3Dscene)
682  {
684  m_3Dscene->getViewport("main");
685  if (gl_view)
686  {
687  double m, M;
688  gl_view->getViewportClipDistances(m, M);
689  gl_view->setViewportClipDistances(m, new_max);
690  }
691  }
692 }
693 
695 {
696 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
698  if (win) return win->m_canvas->cameraFOV();
699 #endif
700  return .0f;
701 }
702 
704 {
705 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
707  if (win) win->m_canvas->setCameraFOV(v);
708 #endif
709 }
710 
711 /*---------------------------------------------------------------
712  getCameraElevationDeg
713  ---------------------------------------------------------------*/
715 {
716 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
717  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
718  return win ? win->m_canvas->getElevationDegrees() : 0;
719 #else
720  return 0;
721 #endif
722 }
723 
724 /*---------------------------------------------------------------
725  getCameraAzimuthDeg
726  ---------------------------------------------------------------*/
728 {
729 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
730  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
731  return win ? win->m_canvas->getAzimuthDegrees() : 0;
732 #else
733  return 0;
734 #endif
735 }
736 
737 /*---------------------------------------------------------------
738  getCameraPointingToPoint
739  ---------------------------------------------------------------*/
741  float& x, float& y, float& z) const
742 {
743 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
744  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
745  if (win)
746  {
747  x = win->m_canvas->getCameraPointingX();
748  y = win->m_canvas->getCameraPointingY();
749  z = win->m_canvas->getCameraPointingZ();
750  }
751  else
752  x = y = z = 0;
753 #else
757 #endif
758 }
759 
760 /*---------------------------------------------------------------
761  getCameraZoom
762  ---------------------------------------------------------------*/
764 {
765 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
766  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
767  return win ? win->m_canvas->getZoomDistance() : 0;
768 #else
769  return 0;
770 #endif
771 }
772 
773 /*---------------------------------------------------------------
774  isCameraProjective
775  ---------------------------------------------------------------*/
777 {
778 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
779  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
780  return win ? win->m_canvas->isCameraProjective() : true;
781 #else
782  return true;
783 #endif
784 }
785 
786 /*---------------------------------------------------------------
787  getLastMousePosition
788  ---------------------------------------------------------------*/
790 {
791 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
792  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
793  if (!win) return false;
794  win->m_canvas->getLastMousePosition(x, y);
795  return true;
796 #else
799  return false;
800 #endif
801 }
802 
803 /*---------------------------------------------------------------
804  getLastMousePositionRay
805  ---------------------------------------------------------------*/
807 {
808  int x, y;
809  if (getLastMousePosition(x, y))
810  {
811  m_csAccess3DScene.lock();
812  m_3Dscene->getViewport("main")->get3DRayForPixelCoord(x, y, ray);
813  m_csAccess3DScene.unlock();
814  return true;
815  }
816  else
817  return false;
818 }
819 
820 /*---------------------------------------------------------------
821  setCursorCross
822  ---------------------------------------------------------------*/
823 void CDisplayWindow3D::setCursorCross(bool cursorIsCross)
824 {
825 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
826  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
827  if (!win) return;
828  win->m_canvas->SetCursor(
829  *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR));
830 #else
831  MRPT_UNUSED_PARAM(cursorIsCross);
832 #endif
833 }
834 
835 /*---------------------------------------------------------------
836  grabImagesStart
837  ---------------------------------------------------------------*/
838 void CDisplayWindow3D::grabImagesStart(const std::string& grab_imgs_prefix)
839 {
840  m_grab_imgs_prefix = grab_imgs_prefix;
841  m_grab_imgs_idx = 0;
842 }
843 
844 /*---------------------------------------------------------------
845  grabImagesStop
846  ---------------------------------------------------------------*/
848 /*---------------------------------------------------------------
849  grabImageGetNextFile
850  ---------------------------------------------------------------*/
852 {
853  if (m_grab_imgs_prefix.empty())
854  return string();
855  else
856  return format(
857  "%s%06u.png", m_grab_imgs_prefix.c_str(), m_grab_imgs_idx++);
858 }
859 
860 /*---------------------------------------------------------------
861  captureImagesStart
862  ---------------------------------------------------------------*/
864 /*---------------------------------------------------------------
865  captureImagesStop
866  ---------------------------------------------------------------*/
868 /*---------------------------------------------------------------
869  getLastWindowImage
870  ---------------------------------------------------------------*/
872 {
873  bool ret;
874 
875  {
876  std::lock_guard<std::mutex> lock(m_last_captured_img_cs);
878  {
879  out_img = *m_last_captured_img; // Copy the full image
880  ret = true;
881  }
882  else
883  ret = false;
884  }
885  return ret;
886 }
887 
888 /*---------------------------------------------------------------
889  getLastWindowImagePtr
890  ---------------------------------------------------------------*/
892 {
893  std::lock_guard<std::mutex> lock(m_last_captured_img_cs);
894  return m_last_captured_img;
895 }
896 
897 /*---------------------------------------------------------------
898  addTextMessage
899  ---------------------------------------------------------------*/
901  const double x_frac, const double y_frac, const std::string& text,
902  const mrpt::utils::TColorf& color, const size_t unique_index,
903  const TOpenGLFont font)
904 {
905 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
907  if (win)
908  {
909  // Send request:
910  // Add a 2D text message:
911  // vector_x: [0]:x, [1]:y, [2,3,4]:R G B, "x": enum of desired font.
912  // "y": unique index, "str": String.
915  REQ->source3D = this;
916  REQ->OPCODE = 360;
917  REQ->str = text;
918  REQ->vector_x.resize(5);
919  REQ->vector_x[0] = x_frac;
920  REQ->vector_x[1] = y_frac;
921  REQ->vector_x[2] = color.R;
922  REQ->vector_x[3] = color.G;
923  REQ->vector_x[4] = color.B;
924  REQ->x = int(font);
925  REQ->y = int(unique_index);
926 
928  }
929 #else
930  MRPT_UNUSED_PARAM(x_frac);
931  MRPT_UNUSED_PARAM(y_frac);
932  MRPT_UNUSED_PARAM(text);
934  MRPT_UNUSED_PARAM(unique_index);
935  MRPT_UNUSED_PARAM(font);
936 #endif
937 }
938 
939 /*---------------------------------------------------------------
940  addTextMessage
941  ---------------------------------------------------------------*/
943  const double x_frac, const double y_frac, const std::string& text,
944  const mrpt::utils::TColorf& color, const std::string& font_name,
945  const double font_size, const mrpt::opengl::TOpenGLFontStyle font_style,
946  const size_t unique_index, const double font_spacing,
947  const double font_kerning, const bool draw_shadow,
948  const mrpt::utils::TColorf& shadow_color)
949 {
950 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
952  if (win)
953  {
954  // Send request:
955  // Add a 2D text message:
958  REQ->source3D = this;
959  REQ->OPCODE = 362;
960  REQ->str = text;
961  REQ->plotName = font_name;
962  REQ->vector_x.resize(12);
963  REQ->vector_x[0] = x_frac;
964  REQ->vector_x[1] = y_frac;
965  REQ->vector_x[2] = color.R;
966  REQ->vector_x[3] = color.G;
967  REQ->vector_x[4] = color.B;
968  REQ->vector_x[5] = font_size;
969  REQ->vector_x[6] = font_spacing;
970  REQ->vector_x[7] = font_kerning;
971  REQ->vector_x[8] = draw_shadow ? 1 : 0;
972  REQ->vector_x[9] = shadow_color.R;
973  REQ->vector_x[10] = shadow_color.G;
974  REQ->vector_x[11] = shadow_color.B;
975 
976  REQ->x = int(font_style);
977  REQ->y = int(unique_index);
978 
980  }
981 #else
982  MRPT_UNUSED_PARAM(x_frac);
983  MRPT_UNUSED_PARAM(y_frac);
984  MRPT_UNUSED_PARAM(text);
986  MRPT_UNUSED_PARAM(font_name);
987  MRPT_UNUSED_PARAM(font_size);
988  MRPT_UNUSED_PARAM(font_style);
989  MRPT_UNUSED_PARAM(unique_index);
990  MRPT_UNUSED_PARAM(font_spacing);
991  MRPT_UNUSED_PARAM(font_kerning);
992  MRPT_UNUSED_PARAM(draw_shadow);
993  MRPT_UNUSED_PARAM(shadow_color);
994 #endif
995 }
996 
997 /*---------------------------------------------------------------
998  clearTextMessages
999  ---------------------------------------------------------------*/
1001 {
1002 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
1004  if (win)
1005  {
1006  // Send request:
1009  REQ->source3D = this;
1010  REQ->OPCODE = 361;
1012  }
1013 #endif
1014 }
1015 
1017 {
1018  const double ALPHA = 0.99;
1019  m_last_FPS = ALPHA * m_last_FPS + (1 - ALPHA) * FPS;
1020 }
1021 
1022 // Called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
1024 {
1025  const mrptEvent3DWindowGrabImageFile ev(this, fil);
1026  publishEvent(ev);
1027 }
1028 
1029 // Returns the "main" viewport of the scene.
1031 {
1032  m_csAccess3DScene.lock();
1033  mrpt::opengl::COpenGLViewport::Ptr view = m_3Dscene->getViewport("main");
1034  m_csAccess3DScene.unlock();
1035  return view;
1036 }
1037 
1039 {
1040  m_csAccess3DScene.lock();
1041  mrpt::opengl::COpenGLViewport::Ptr view = m_3Dscene->getViewport("main");
1042  view->setImageView(img);
1043  m_csAccess3DScene.unlock();
1044 }
1045 
1047 {
1048  m_csAccess3DScene.lock();
1049  mrpt::opengl::COpenGLViewport::Ptr view = m_3Dscene->getViewport("main");
1050  view->setImageView_fast(img);
1051  m_csAccess3DScene.unlock();
1052 }
1053 
1056  : m_win(win)
1057 {
1058  out_scene_ptr = m_win.get3DSceneAndLock();
1059 }
1061  : m_win(win)
1062 {
1064 }
1066 {
1068 }
An event sent by a window upon resize.
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. ...
static void pushPendingWxRequest(TRequestToWxMainThread *data)
Thread-safe method to insert a new pending request (The memory must be dinamically allocated with "ne...
An event sent by a CDisplayWindow3D window when an image is saved after enabling this feature with CD...
void OnMenuAbout(wxCommandEvent &event)
void unlockAccess3DScene()
Unlocks the access to the internal 3D scene.
GLAPI void GLAPIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
An event sent by a window upon a mouse click, giving the (x,y) pixel coordinates. ...
std::recursive_mutex m_csAccess3DScene
Critical section for accesing m_3Dscene.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
std::shared_ptr< COpenGLViewport > Ptr
void OnClose(wxCloseEvent &event)
GLdouble GLdouble z
Definition: glext.h:3872
mrpt::gui::CDisplayWindow3D * source3D
Only one of source* can be non-nullptr, indicating the class that generated the request.
Definition: WxSubsystem.h:214
mrpt::utils::CImage::Ptr getLastWindowImagePtr() const
Retrieve the last captured image from the window, as a smart pointer.
The data structure for each inter-thread request:
Definition: WxSubsystem.h:193
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...
#define _U(x)
Definition: WxSubsystem.h:506
void setWindowTitle(const std::string &str) override
Changes the window title.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
std::string m_caption
The caption of the window.
mrpt::opengl::COpenGLScene::Ptr & get3DSceneAndLock()
Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introductio...
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:118
void grabImagesStart(const std::string &grab_imgs_prefix=std::string("video_"))
Start to save rendered images to disk.
static int notifyWindowCreation()
Atomically increments the number of windows created with the main frame as parent.
void resize(unsigned int width, unsigned int height) override
Resizes the window, stretching the image to fit into the display area.
Keeps a list of text messages which can be rendered to OpenGL contexts by graphic classes...
#define THROW_EXCEPTION(msg)
A pair (x,y) of pixel coordinates (integer resolution).
Definition: TPixelCoord.h:38
void setCameraPointingToPoint(float x, float y, float z)
Changes the camera parameters programmatically.
mrptKeyModifier
Definition: keycodes.h:159
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:76
void OnMenuClose(wxCommandEvent &event)
static wxBitmap getMRPTDefaultIcon()
GLAPI void GLAPIENTRY glReadBuffer(GLenum mode)
STL namespace.
CDisplayWindow3D * m_win3D
Definition: WxSubsystem.h:408
static CDisplayWindow3D::Ptr Create(const std::string &windowCaption, unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Class factory returning a smart pointer.
#define GL_UNSIGNED_BYTE
Definition: glew.h:302
void internal_emitGrabImageEvent(const std::string &fil)
called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
bool hasSubscribers() const
Can be called by a derived class before preparing an event for publishing with publishEvent to determ...
Definition: CObservable.h:57
void setCameraProjective(bool isProjective)
Sets the camera as projective, or orthogonal.
float getCameraZoom() const
Get camera parameters programmatically.
void setImageView_fast(mrpt::utils::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.
void OnResize(wxSizeEvent &event)
int OPCODE
Valid codes are: For CDisplayWindow:
Definition: WxSubsystem.h:300
An event sent by a window upon when it&#39;s about to be closed, either manually by the user or programma...
An event sent by a window when the mouse is moved over it.
GLenum GLsizei width
Definition: glext.h:3531
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
void OnChar(wxKeyEvent &event)
void setImageView(const mrpt::utils::CImage &img)
Set the "main" viewport into "image view"-mode, where an image is efficiently drawn (fitting the view...
void notifyChildWindowDestruction()
Called by wx main thread to set m_hwnd to NULL.
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
void publishEvent(const mrptEvent &e) const
Called when you want this object to emit an event to all the observers currently subscribed to this o...
Definition: CObservable.cpp:47
const long ID_MENUITEM1
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
#define GL_BGR_EXT
Definition: glew.h:5354
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.
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
void addTextMessage(const double x_frac, const double y_frac, const std::string &text, const mrpt::utils::TColorf &color, const size_t unique_index, const mrpt::opengl::TOpenGLFont font)
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...
bool getLastWindowImage(mrpt::utils::CImage &out_img) const
Retrieve the last captured image from the window.
GLint GLvoid * img
Definition: glext.h:3763
TOpenGLFontStyle
Different style for vectorized font rendering.
Definition: opengl_fonts.h:36
bool isOpen()
Returns false if the user has already closed the window.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
std::shared_ptr< CImage > Ptr
Definition: CImage.h:120
std::shared_ptr< CDisplayWindow3D > Ptr
An event sent by a window upon a char pressed by the user.
const long ID_MENUITEM2
GLsizei const GLchar ** string
Definition: glext.h:4101
mrptKeyModifier keyEventToMrptKeyModifier(const wxKeyEvent &ev)
Extracts the key modifiers from a wxKeyEvent.
Definition: WxUtils.cpp:1135
mrpt::utils::CImage::Ptr m_last_captured_img
volatile mrptKeyModifier m_keyPushedModifier
void forceRepaint()
Repaints the window.
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
This class implements the GUI thread required for the wxWidgets-based GUI.
Definition: WxSubsystem.h:100
Definition: inftrees.h:28
void grabImagesStop()
Stops image grabbing started by grabImagesStart.
GLuint id
Definition: glext.h:3909
std::shared_ptr< COpenGLScene > Ptr
Definition: COpenGLScene.h:62
bool isCameraProjective() const
Sets the camera as projective, or orthogonal.
void setCameraZoom(float zoom)
Changes the camera parameters programmatically.
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
GLuint const GLchar * name
Definition: glext.h:4054
A RGB color - floats in the range [0,1].
Definition: TColor.h:78
virtual void setCursorCross(bool cursorIsCross) override
Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) ...
void destroyWxWindow()
Must be called by child classes in their destructors.
GLenum GLint GLint y
Definition: glext.h:3538
void setMinRange(double new_min)
Changes the camera min clip range (z) (used for gluPerspective).
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:16
void createWxWindow(unsigned int initialWidth, unsigned int initialHeight)
Must be called by child classes just within the constructor.
void captureImagesStop()
Stop image grabbing.
GLsizeiptr size
Definition: glext.h:3923
CDisplayWindow3D(const std::string &windowCaption=std::string(), unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Constructor.
double timeDifference(const mrpt::system::TTimeStamp t_first, const mrpt::system::TTimeStamp t_later)
Returns the time difference from t1 to t2 (positive if t2 is posterior to t1), in seconds...
Definition: datetime.cpp:208
GLenum GLint x
Definition: glext.h:3538
GLenum GLsizei GLsizei height
Definition: glext.h:3554
std::string str
Parameters, depending on OPCODE.
Definition: WxSubsystem.h:226
#define GL_FRONT
Definition: glew.h:317
void internal_setRenderingFPS(double FPS)
Set the rendering FPS (users don&#39;t call this, the method is for internal MRPT objects only) ...
std::promise< void > m_windowDestroyed
This semaphore will be signaled when the wx window is destroyed.
void clearTextMessages()
Clear all text messages created with addTextMessage().
mrpt::utils::void_ptr_noncopy m_hwnd
The window handle.
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).
static int notifyWindowDestruction()
Atomically decrements the number of windows created with the main frame as parent.
void setCameraAzimuthDeg(float deg)
Changes the camera parameters programmatically.
void addTextMessage(const double x, const double y, const std::string &text, const mrpt::utils::TColorf &color=mrpt::utils::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.
void setCameraElevationDeg(float deg)
Changes the camera parameters programmatically.
CMyGLCanvas_DisplayWindow3D * m_canvas
Definition: WxSubsystem.h:411
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: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019