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-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 
10 #include "gui-precomp.h" // Precompiled headers
11 
12 #include <mrpt/config.h>
13 
15 #include <mrpt/img/CImage.h>
16 #include <mrpt/system/CTicTac.h>
17 
18 #include <mrpt/gui/WxSubsystem.h>
19 #include <mrpt/gui/WxUtils.h>
20 
21 #if MRPT_HAS_OPENGL_GLUT
22 #ifdef _WIN32
23 // Windows:
24 #include <windows.h>
25 #endif
26 
27 #ifdef __APPLE__
28 #include <OpenGL/gl.h>
29 #include <OpenGL/glu.h>
30 #include <GLUT/glut.h>
31 #else
32 #include <GL/gl.h>
33 #include <GL/glu.h>
34 #include <GL/glut.h>
35 #ifdef HAVE_FREEGLUT_EXT_H
36 #include <GL/freeglut_ext.h>
37 #endif
38 #endif
39 #endif
40 
41 using namespace mrpt;
42 using namespace mrpt::gui;
43 using namespace mrpt::opengl;
44 using namespace mrpt::math;
45 using namespace mrpt::img;
46 using namespace std;
47 
48 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
49 
50 #if !wxUSE_GLCANVAS
51 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild wxWidgets"
52 #endif
53 
56 
57 namespace mrpt::gui
58 {
59 class CMyGLCanvas_DisplayWindow3D : public mrpt::gui::CWxGLCanvasBase
60 {
61  public:
62  CMyGLCanvas_DisplayWindow3D(
63  CDisplayWindow3D* win3D, wxWindow* parent, wxWindowID id = wxID_ANY,
64  const wxPoint& pos = wxDefaultPosition,
65  const wxSize& size = wxDefaultSize, long style = 0,
66  const wxString& name = _T("CMyGLCanvas_DisplayWindow3D"));
67 
68  virtual ~CMyGLCanvas_DisplayWindow3D();
69 
70  CDisplayWindow3D* m_win3D = nullptr;
71 
72  // The idea is that CMyGLCanvas_DisplayWindow3D was derived from
73  // CTextMessageCapable, but
74  // that raises errors in MSVC when converting method pointers to
75  // wxObjectEventFunction...
76  struct THubClass : public mrpt::opengl::CTextMessageCapable
77  {
78  void render_text_messages_public(const int w, const int h) const
79  {
80  render_text_messages(w, h);
81  }
82  };
83  THubClass m_text_msgs;
84 
85  void OnCharCustom(wxKeyEvent& event);
86  void OnMouseDown(wxMouseEvent& event);
87  void OnMouseMove(wxMouseEvent& event);
88 
89  void OnPreRender();
90  void OnPostRender();
91  void OnPostRenderSwapBuffers(double At, wxPaintDC& dc);
92 
93  static void display3D_processKeyEvent(
94  CDisplayWindow3D* m_win3D, wxKeyEvent& ev);
95 };
96 }
97 
98 CMyGLCanvas_DisplayWindow3D::CMyGLCanvas_DisplayWindow3D(
99  CDisplayWindow3D* win3D, wxWindow* parent, wxWindowID id,
100  const wxPoint& pos, const wxSize& size, long style, const wxString& name)
101  : CWxGLCanvasBase(parent, id, pos, size, style, name), m_win3D(win3D)
102 {
103  this->Bind(wxEVT_CHAR, &CMyGLCanvas_DisplayWindow3D::OnCharCustom, this);
104  this->Bind(
105  wxEVT_CHAR_HOOK, &CMyGLCanvas_DisplayWindow3D::OnCharCustom, this);
106  this->Bind(
107  wxEVT_LEFT_DOWN, &CMyGLCanvas_DisplayWindow3D::OnMouseDown, this);
108  this->Bind(
109  wxEVT_RIGHT_DOWN, &CMyGLCanvas_DisplayWindow3D::OnMouseDown, this);
110  this->Bind(wxEVT_MOTION, &CMyGLCanvas_DisplayWindow3D::OnMouseMove, this);
111 }
112 
113 void CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(
114  CDisplayWindow3D* m_win3D, wxKeyEvent& ev)
115 {
116  if (m_win3D)
117  {
118  if (ev.AltDown() && ev.GetKeyCode() == MRPTK_RETURN)
119  {
121  m_win3D->m_lastFullScreen, mrpt::system::now()) > 0.2)
122  {
123  m_win3D->m_lastFullScreen = mrpt::system::now();
124  cout << "[CDisplayWindow3D] Switching fullscreen...\n";
125  C3DWindowDialog* win = (C3DWindowDialog*)m_win3D->m_hwnd.get();
126  if (win)
127  {
128  win->ShowFullScreen(!win->IsFullScreen());
129  }
130  }
131  // Alt+Enter: Don't notify on this key stroke, since if we're
132  // switching to fullscreen
133  // and the user is waiting for a key to close the window, a runtime
134  // crash will occur,
135  // so return now:
136  return;
137  }
138 
139  const int code = ev.GetKeyCode();
141 
142  m_win3D->m_keyPushedCode = code;
143  m_win3D->m_keyPushedModifier = mod;
144  m_win3D->m_keyPushed = true;
145 
146  // Send the event:
147  try
148  {
149  m_win3D->publishEvent(mrptEventWindowChar(m_win3D, code, mod));
150  }
151  catch (...)
152  {
153  }
154  }
155  // ev.Skip(); // Pass the event to whoever else.
156 }
157 
158 void CMyGLCanvas_DisplayWindow3D::OnCharCustom(wxKeyEvent& ev)
159 {
160  CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(m_win3D, ev);
161 }
162 
163 void CMyGLCanvas_DisplayWindow3D::OnMouseDown(wxMouseEvent& event)
164 {
165  // Send the event:
166  if (m_win3D && m_win3D->hasSubscribers())
167  {
168  try
169  {
171  m_win3D, TPixelCoord(event.GetX(), event.GetY()),
172  event.LeftDown(), event.RightDown()));
173  }
174  catch (...)
175  {
176  }
177  }
178 
179  event.Skip(); // so it's processed by the wx system!
180 }
181 
182 void CMyGLCanvas_DisplayWindow3D::OnMouseMove(wxMouseEvent& event)
183 {
184  // Send the event:
185  if (m_win3D && m_win3D->hasSubscribers())
186  {
187  try
188  {
190  m_win3D, TPixelCoord(event.GetX(), event.GetY()),
191  event.LeftDown(), event.RightDown()));
192  }
193  catch (...)
194  {
195  }
196  }
197 
198  event.Skip(); // so it's processed by the wx system!
199 }
200 
201 CMyGLCanvas_DisplayWindow3D::~CMyGLCanvas_DisplayWindow3D()
202 {
203  getOpenGLSceneRef().reset(); // Avoid the base class to free this object
204  // (it's freed by CDisplayWindow3D)
205 }
206 
207 void CMyGLCanvas_DisplayWindow3D::OnPreRender()
208 {
209  auto& openGLSceneRef = getOpenGLSceneRef();
210  if (openGLSceneRef) openGLSceneRef.reset();
211 
212  COpenGLScene::Ptr& ptrScene = m_win3D->get3DSceneAndLock();
213  if (ptrScene) openGLSceneRef = ptrScene;
214 }
215 
216 void CMyGLCanvas_DisplayWindow3D::OnPostRender()
217 {
218  // Avoid the base class to free this object (it's freed by CDisplayWindow3D)
219  getOpenGLSceneRef().reset();
220  m_win3D->unlockAccess3DScene();
221 
222  // If any, draw the 2D text messages:
223  int w, h;
224  this->GetSize(&w, &h);
225 
226  m_text_msgs.render_text_messages_public(w, h);
227 }
228 
229 void CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers(
230  double At, wxPaintDC& dc)
231 {
232  if (m_win3D) m_win3D->internal_setRenderingFPS(At > 0 ? 1.0 / At : 1e9);
233 
234  // If we are requested to do so, grab images to disk as they are rendered:
235  string grabFile;
236  if (m_win3D) grabFile = m_win3D->grabImageGetNextFile();
237  if (m_win3D && (!grabFile.empty() || m_win3D->isCapturingImgs()))
238  {
239  int w, h;
240  dc.GetSize(&w, &h);
241 
242  // Save image directly from OpenGL - It could also use 4 channels and
243  // save with GL_BGRA_EXT
244  CImage::Ptr frame(new CImage(w, h, 3, false));
246  glReadPixels(0, 0, w, h, GL_BGR_EXT, GL_UNSIGNED_BYTE, (*frame)(0, 0));
247 
248  if (!grabFile.empty())
249  {
250  frame->saveToFile(grabFile);
251  m_win3D->internal_emitGrabImageEvent(grabFile);
252  }
253 
254  if (m_win3D->isCapturingImgs())
255  {
256  {
257  std::lock_guard<std::mutex> lock(
258  m_win3D->m_last_captured_img_cs);
259  m_win3D->m_last_captured_img = frame;
260  frame.reset();
261  }
262  }
263  }
264 }
265 
266 #endif // Wx + OpenGL
267 
268 #if MRPT_HAS_WXWIDGETS
269 
270 BEGIN_EVENT_TABLE(C3DWindowDialog, wxFrame)
271 
272 END_EVENT_TABLE()
273 
274 const long C3DWindowDialog::ID_MENUITEM1 = wxNewId();
275 const long C3DWindowDialog::ID_MENUITEM2 = wxNewId();
276 
278  CDisplayWindow3D* win3D, WxSubsystem::CWXMainFrame* parent, wxWindowID id,
279  const std::string& caption, wxSize initialSize)
280  : m_win3D(win3D), m_mainFrame(parent)
281 {
282 #if MRPT_HAS_OPENGL_GLUT
283 
284  Create(
285  parent, id, _U(caption.c_str()), wxDefaultPosition, initialSize,
286  wxDEFAULT_FRAME_STYLE, _T("id"));
287 
288  wxIcon FrameIcon;
289  FrameIcon.CopyFromBitmap(mrpt::gui::WxSubsystem::getMRPTDefaultIcon());
290  SetIcon(FrameIcon);
291 
292  // Create the wxCanvas object:
293  m_canvas = new CMyGLCanvas_DisplayWindow3D(
294  win3D, this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
295 
296  // Events:
297  this->Bind(wxEVT_CLOSE_WINDOW, &C3DWindowDialog::OnClose, this);
298  this->Bind(
299  wxEVT_COMMAND_MENU_SELECTED, &C3DWindowDialog::OnMenuClose, this,
300  ID_MENUITEM1);
301  this->Bind(
302  wxEVT_COMMAND_MENU_SELECTED, &C3DWindowDialog::OnMenuAbout, this,
303  ID_MENUITEM2);
304  this->Bind(wxEVT_CHAR, &C3DWindowDialog::OnChar, this);
305  this->Bind(wxEVT_SIZE, &C3DWindowDialog::OnResize, this);
306 
307  // Increment number of windows:
308  // int winCount =
310 // cout << "[C3DWindowDialog] Notifying new window: " << winCount << endl;
311 #else
312  THROW_EXCEPTION("MRPT was compiled without OpenGL support");
313 #endif
314  // this->Iconize(false);
315 }
316 
317 // Destructor
319 {
320  // cout << "[C3DWindowDialog::~C3DWindowDialog]" << endl;
321 }
322 
323 // OnClose event:
324 void C3DWindowDialog::OnClose(wxCloseEvent& event)
325 {
326  // Send the event:
327  bool allow_close = true;
328  try
329  {
330  mrptEventWindowClosed ev(m_win3D, true /* allow close */);
331  m_win3D->publishEvent(ev);
332  allow_close = ev.allow_close;
333  }
334  catch (...)
335  {
336  }
337  if (!allow_close) return; // Don't process this close event.
338 
339  // cout << "[C3DWindowDialog::OnClose]" << endl;
340  // Set the m_hwnd=nullptr in our parent object.
342 
343  // Decrement number of windows:
345 
346  // Signal we are destroyed:
347  m_win3D->m_windowDestroyed.set_value();
348 
349  event.Skip(); // keep processing by parent classes.
350 }
351 
352 // Menu: Close
353 void C3DWindowDialog::OnMenuClose(wxCommandEvent& event) { Close(); }
354 // Menu: About
355 void C3DWindowDialog::OnMenuAbout(wxCommandEvent& event)
356 {
357  ::wxMessageBox(
358  _("3D Scene viewer\n Class gui::CDisplayWindow3D\n MRPT C++ library"),
359  _("About..."));
360 }
361 
362 void C3DWindowDialog::OnChar(wxKeyEvent& ev)
363 {
364 #if MRPT_HAS_OPENGL_GLUT
365  CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(m_win3D, ev);
366 #endif
367 }
368 
369 void C3DWindowDialog::OnResize(wxSizeEvent& event)
370 {
371 #if MRPT_HAS_OPENGL_GLUT
372  // Send the event:
373  if (m_win3D)
374  {
375  try
376  {
378  m_win3D, event.GetSize().GetWidth(),
379  event.GetSize().GetHeight()));
380  }
381  catch (...)
382  {
383  }
384  }
385  event.Skip(); // so it's processed by the wx system!
386 #endif
387 }
388 
390 {
391 #if MRPT_HAS_OPENGL_GLUT
392  m_canvas->m_text_msgs.clearTextMessages();
393 #endif
394 }
395 
397  const double x_frac, const double y_frac, const std::string& text,
398  const mrpt::img::TColorf& color, const size_t unique_index,
399  const mrpt::opengl::TOpenGLFont font)
400 {
401 #if MRPT_HAS_OPENGL_GLUT
402  m_canvas->m_text_msgs.addTextMessage(
403  x_frac, y_frac, text, color, unique_index, font);
404 #endif
405 }
406 
408  const double x_frac, const double y_frac, const std::string& text,
409  const mrpt::img::TColorf& color, const std::string& font_name,
410  const double font_size, const mrpt::opengl::TOpenGLFontStyle font_style,
411  const size_t unique_index, const double font_spacing,
412  const double font_kerning, const bool has_shadow,
413  const mrpt::img::TColorf& shadow_color)
414 {
415 #if MRPT_HAS_OPENGL_GLUT
416  m_canvas->m_text_msgs.addTextMessage(
417  x_frac, y_frac, text, color, font_name, font_size, font_style,
418  unique_index, font_spacing, font_kerning, has_shadow, shadow_color);
419 #endif
420 }
421 
422 #endif // MRPT_HAS_WXWIDGETS
423 
424 /*---------------------------------------------------------------
425  Constructor
426  ---------------------------------------------------------------*/
428  const std::string& windowCaption, unsigned int initialWindowWidth,
429  unsigned int initialWindowHeight)
430  : CBaseGUIWindow(static_cast<void*>(this), 300, 399, windowCaption),
431  m_grab_imgs_prefix(),
432  m_grab_imgs_idx(0),
433  m_is_capturing_imgs(false),
434  m_lastFullScreen(mrpt::system::now()),
435  m_last_FPS(10)
436 {
437  // static mrpt::utils::CStdOutStream oo;
438  // m_csAccess3DScene.m_debugOut = &oo;
439 
440  m_3Dscene = COpenGLScene::Create();
441  CBaseGUIWindow::createWxWindow(initialWindowWidth, initialWindowHeight);
442 }
443 
445  const std::string& windowCaption, unsigned int initialWindowWidth,
446  unsigned int initialWindowHeight)
447 {
449  windowCaption, initialWindowWidth, initialWindowHeight));
450 }
451 /*---------------------------------------------------------------
452  Destructor
453  ---------------------------------------------------------------*/
455 {
456  // get lock so we make sure nobody else is touching the window right now.
457  m_csAccess3DScene.lock();
458  m_csAccess3DScene.unlock();
459 
461 }
462 
463 /*---------------------------------------------------------------
464  resize
465  ---------------------------------------------------------------*/
466 void CDisplayWindow3D::resize(unsigned int width, unsigned int height)
467 {
468 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
469  if (!isOpen())
470  {
471  cerr << "[CDisplayWindow3D::setPos] Window closed!: " << m_caption
472  << endl;
473  return;
474  }
475 
476  // Send a request to destroy this object:
479  REQ->source3D = this;
480  REQ->OPCODE = 303;
481  REQ->x = width;
482  REQ->y = height;
484 #else
487 #endif
488 }
489 
490 /*---------------------------------------------------------------
491  setPos
492  ---------------------------------------------------------------*/
494 {
495 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
496  if (!isOpen())
497  {
498  cerr << "[CDisplayWindow3D::setPos] Window closed!: " << m_caption
499  << endl;
500  return;
501  }
502 
503  // Send a request to destroy this object:
506  REQ->source3D = this;
507  REQ->OPCODE = 302;
508  REQ->x = x;
509  REQ->y = y;
511 #else
514 #endif
515 }
516 
517 /*---------------------------------------------------------------
518  setWindowTitle
519  ---------------------------------------------------------------*/
521 {
522 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
523  if (!isOpen())
524  {
525  cerr << "[CDisplayWindow3D::setWindowTitle] Window closed!: "
526  << m_caption << endl;
527  return;
528  }
529 
530  // Send a request to destroy this object:
533  REQ->source3D = this;
534  REQ->OPCODE = 304;
535  REQ->str = str;
537 #else
538  MRPT_UNUSED_PARAM(str);
539 #endif
540 }
541 
542 /*---------------------------------------------------------------
543  get3DSceneAndLock
544  ---------------------------------------------------------------*/
546 {
547  m_csAccess3DScene.lock();
548  return m_3Dscene;
549 }
550 
551 /*---------------------------------------------------------------
552  unlockAccess3DScene
553  ---------------------------------------------------------------*/
555 /*---------------------------------------------------------------
556  forceRepaint
557  ---------------------------------------------------------------*/
559 {
560 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
562  if (win)
563  {
564  // win->Refresh(false); // Do not erase background
565  // We must do this from the wx thread!
566 
567  // Send refresh request:
570  REQ->source3D = this;
571  REQ->OPCODE = 350;
573  }
574 #endif
575 }
576 
577 /*---------------------------------------------------------------
578  setCameraElevationDeg
579  ---------------------------------------------------------------*/
581 {
582 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
584  if (win) win->m_canvas->setElevationDegrees(deg);
585 #else
586  MRPT_UNUSED_PARAM(deg);
587 #endif
588 }
589 
591 {
592 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
594  if (win) win->m_canvas->setUseCameraFromScene(useIt);
595 #else
596  MRPT_UNUSED_PARAM(useIt);
597 #endif
598 }
599 
600 /*---------------------------------------------------------------
601  setCameraAzimuthDeg
602  ---------------------------------------------------------------*/
604 {
605 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
607  if (win) win->m_canvas->setAzimuthDegrees(deg);
608 #else
609  MRPT_UNUSED_PARAM(deg);
610 #endif
611 }
612 
613 /*---------------------------------------------------------------
614  setCameraPointingToPoint
615  ---------------------------------------------------------------*/
617 {
618 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
620  if (win)
621  {
622  win->m_canvas->setCameraPointing(x, y, z);
623  }
624 #else
628 #endif
629 }
630 
631 /*---------------------------------------------------------------
632  setCameraZoom
633  ---------------------------------------------------------------*/
635 {
636 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
638  if (win) win->m_canvas->setZoomDistance(zoom);
639 #else
640  MRPT_UNUSED_PARAM(zoom);
641 #endif
642 }
643 
644 /*---------------------------------------------------------------
645  setCameraProjective
646  ---------------------------------------------------------------*/
648 {
649 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
651  if (win) win->m_canvas->setCameraProjective(isProjective);
652 #else
653  MRPT_UNUSED_PARAM(isProjective);
654 #endif
655 }
656 
657 void CDisplayWindow3D::setMinRange(double new_min)
658 {
659  if (m_3Dscene)
660  {
662  m_3Dscene->getViewport("main");
663  if (gl_view)
664  {
665  double m, M;
666  gl_view->getViewportClipDistances(m, M);
667  gl_view->setViewportClipDistances(new_min, M);
668  }
669  }
670 }
671 void CDisplayWindow3D::setMaxRange(double new_max)
672 {
673  if (m_3Dscene)
674  {
676  m_3Dscene->getViewport("main");
677  if (gl_view)
678  {
679  double m, M;
680  gl_view->getViewportClipDistances(m, M);
681  gl_view->setViewportClipDistances(m, new_max);
682  }
683  }
684 }
685 
687 {
688 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
690  if (win) return win->m_canvas->cameraFOV();
691 #endif
692  return .0f;
693 }
694 
696 {
697 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
699  if (win) win->m_canvas->setCameraFOV(v);
700 #endif
701 }
702 
703 /*---------------------------------------------------------------
704  getCameraElevationDeg
705  ---------------------------------------------------------------*/
707 {
708 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
709  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
710  return win ? win->m_canvas->getElevationDegrees() : 0;
711 #else
712  return 0;
713 #endif
714 }
715 
716 /*---------------------------------------------------------------
717  getCameraAzimuthDeg
718  ---------------------------------------------------------------*/
720 {
721 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
722  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
723  return win ? win->m_canvas->getAzimuthDegrees() : 0;
724 #else
725  return 0;
726 #endif
727 }
728 
729 /*---------------------------------------------------------------
730  getCameraPointingToPoint
731  ---------------------------------------------------------------*/
733  float& x, float& y, float& z) const
734 {
735 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
736  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
737  if (win)
738  {
739  x = win->m_canvas->getCameraPointingX();
740  y = win->m_canvas->getCameraPointingY();
741  z = win->m_canvas->getCameraPointingZ();
742  }
743  else
744  x = y = z = 0;
745 #else
749 #endif
750 }
751 
752 /*---------------------------------------------------------------
753  getCameraZoom
754  ---------------------------------------------------------------*/
756 {
757 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
758  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
759  return win ? win->m_canvas->getZoomDistance() : 0;
760 #else
761  return 0;
762 #endif
763 }
764 
765 /*---------------------------------------------------------------
766  isCameraProjective
767  ---------------------------------------------------------------*/
769 {
770 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
771  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
772  return win ? win->m_canvas->isCameraProjective() : true;
773 #else
774  return true;
775 #endif
776 }
777 
778 /*---------------------------------------------------------------
779  getLastMousePosition
780  ---------------------------------------------------------------*/
782 {
783 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
784  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
785  if (!win) return false;
786  win->m_canvas->getLastMousePosition(x, y);
787  return true;
788 #else
791  return false;
792 #endif
793 }
794 
795 /*---------------------------------------------------------------
796  getLastMousePositionRay
797  ---------------------------------------------------------------*/
799 {
800  int x, y;
801  if (getLastMousePosition(x, y))
802  {
803  m_csAccess3DScene.lock();
804  m_3Dscene->getViewport("main")->get3DRayForPixelCoord(x, y, ray);
805  m_csAccess3DScene.unlock();
806  return true;
807  }
808  else
809  return false;
810 }
811 
812 /*---------------------------------------------------------------
813  setCursorCross
814  ---------------------------------------------------------------*/
815 void CDisplayWindow3D::setCursorCross(bool cursorIsCross)
816 {
817 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
818  const C3DWindowDialog* win = (const C3DWindowDialog*)m_hwnd.get();
819  if (!win) return;
820  win->m_canvas->SetCursor(
821  *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR));
822 #else
823  MRPT_UNUSED_PARAM(cursorIsCross);
824 #endif
825 }
826 
827 /*---------------------------------------------------------------
828  grabImagesStart
829  ---------------------------------------------------------------*/
830 void CDisplayWindow3D::grabImagesStart(const std::string& grab_imgs_prefix)
831 {
832  m_grab_imgs_prefix = grab_imgs_prefix;
833  m_grab_imgs_idx = 0;
834 }
835 
836 /*---------------------------------------------------------------
837  grabImagesStop
838  ---------------------------------------------------------------*/
840 /*---------------------------------------------------------------
841  grabImageGetNextFile
842  ---------------------------------------------------------------*/
844 {
845  if (m_grab_imgs_prefix.empty())
846  return string();
847  else
848  return format(
849  "%s%06u.png", m_grab_imgs_prefix.c_str(), m_grab_imgs_idx++);
850 }
851 
852 /*---------------------------------------------------------------
853  captureImagesStart
854  ---------------------------------------------------------------*/
856 /*---------------------------------------------------------------
857  captureImagesStop
858  ---------------------------------------------------------------*/
860 /*---------------------------------------------------------------
861  getLastWindowImage
862  ---------------------------------------------------------------*/
864 {
865  bool ret;
866 
867  {
868  std::lock_guard<std::mutex> lock(m_last_captured_img_cs);
870  {
871  out_img = *m_last_captured_img; // Copy the full image
872  ret = true;
873  }
874  else
875  ret = false;
876  }
877  return ret;
878 }
879 
880 /*---------------------------------------------------------------
881  getLastWindowImagePtr
882  ---------------------------------------------------------------*/
884 {
885  std::lock_guard<std::mutex> lock(m_last_captured_img_cs);
886  return m_last_captured_img;
887 }
888 
889 /*---------------------------------------------------------------
890  addTextMessage
891  ---------------------------------------------------------------*/
893  const double x_frac, const double y_frac, const std::string& text,
894  const mrpt::img::TColorf& color, const size_t unique_index,
895  const TOpenGLFont font)
896 {
897 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
899  if (win)
900  {
901  // Send request:
902  // Add a 2D text message:
903  // vector_x: [0]:x, [1]:y, [2,3,4]:R G B, "x": enum of desired font.
904  // "y": unique index, "str": String.
907  REQ->source3D = this;
908  REQ->OPCODE = 360;
909  REQ->str = text;
910  REQ->vector_x.resize(5);
911  REQ->vector_x[0] = x_frac;
912  REQ->vector_x[1] = y_frac;
913  REQ->vector_x[2] = color.R;
914  REQ->vector_x[3] = color.G;
915  REQ->vector_x[4] = color.B;
916  REQ->x = int(font);
917  REQ->y = int(unique_index);
918 
920  }
921 #else
922  MRPT_UNUSED_PARAM(x_frac);
923  MRPT_UNUSED_PARAM(y_frac);
924  MRPT_UNUSED_PARAM(text);
926  MRPT_UNUSED_PARAM(unique_index);
927  MRPT_UNUSED_PARAM(font);
928 #endif
929 }
930 
931 /*---------------------------------------------------------------
932  addTextMessage
933  ---------------------------------------------------------------*/
935  const double x_frac, const double y_frac, const std::string& text,
936  const mrpt::img::TColorf& color, const std::string& font_name,
937  const double font_size, const mrpt::opengl::TOpenGLFontStyle font_style,
938  const size_t unique_index, const double font_spacing,
939  const double font_kerning, const bool draw_shadow,
940  const mrpt::img::TColorf& shadow_color)
941 {
942 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
944  if (win)
945  {
946  // Send request:
947  // Add a 2D text message:
950  REQ->source3D = this;
951  REQ->OPCODE = 362;
952  REQ->str = text;
953  REQ->plotName = font_name;
954  REQ->vector_x.resize(12);
955  REQ->vector_x[0] = x_frac;
956  REQ->vector_x[1] = y_frac;
957  REQ->vector_x[2] = color.R;
958  REQ->vector_x[3] = color.G;
959  REQ->vector_x[4] = color.B;
960  REQ->vector_x[5] = font_size;
961  REQ->vector_x[6] = font_spacing;
962  REQ->vector_x[7] = font_kerning;
963  REQ->vector_x[8] = draw_shadow ? 1 : 0;
964  REQ->vector_x[9] = shadow_color.R;
965  REQ->vector_x[10] = shadow_color.G;
966  REQ->vector_x[11] = shadow_color.B;
967 
968  REQ->x = int(font_style);
969  REQ->y = int(unique_index);
970 
972  }
973 #else
974  MRPT_UNUSED_PARAM(x_frac);
975  MRPT_UNUSED_PARAM(y_frac);
976  MRPT_UNUSED_PARAM(text);
978  MRPT_UNUSED_PARAM(font_name);
979  MRPT_UNUSED_PARAM(font_size);
980  MRPT_UNUSED_PARAM(font_style);
981  MRPT_UNUSED_PARAM(unique_index);
982  MRPT_UNUSED_PARAM(font_spacing);
983  MRPT_UNUSED_PARAM(font_kerning);
984  MRPT_UNUSED_PARAM(draw_shadow);
985  MRPT_UNUSED_PARAM(shadow_color);
986 #endif
987 }
988 
989 /*---------------------------------------------------------------
990  clearTextMessages
991  ---------------------------------------------------------------*/
993 {
994 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
996  if (win)
997  {
998  // Send request:
1001  REQ->source3D = this;
1002  REQ->OPCODE = 361;
1004  }
1005 #endif
1006 }
1007 
1009 {
1010  const double ALPHA = 0.99;
1011  m_last_FPS = ALPHA * m_last_FPS + (1 - ALPHA) * FPS;
1012 }
1013 
1014 // Called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
1016 {
1017  const mrptEvent3DWindowGrabImageFile ev(this, fil);
1018  publishEvent(ev);
1019 }
1020 
1021 // Returns the "main" viewport of the scene.
1023 {
1024  m_csAccess3DScene.lock();
1025  mrpt::opengl::COpenGLViewport::Ptr view = m_3Dscene->getViewport("main");
1026  m_csAccess3DScene.unlock();
1027  return view;
1028 }
1029 
1031 {
1032  m_csAccess3DScene.lock();
1033  mrpt::opengl::COpenGLViewport::Ptr view = m_3Dscene->getViewport("main");
1034  view->setImageView(img);
1035  m_csAccess3DScene.unlock();
1036 }
1037 
1039 {
1040  m_csAccess3DScene.lock();
1041  mrpt::opengl::COpenGLViewport::Ptr view = m_3Dscene->getViewport("main");
1042  view->setImageView_fast(img);
1043  m_csAccess3DScene.unlock();
1044 }
1045 
1048  : m_win(win)
1049 {
1050  out_scene_ptr = m_win.get3DSceneAndLock();
1051 }
1053  : m_win(win)
1054 {
1056 }
1058 {
1060 }
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.
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:211
mrpt::img::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:190
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:503
void setWindowTitle(const std::string &str) override
Changes the window title.
void addTextMessage(const double x_frac, const double y_frac, const std::string &text, const mrpt::img::TColorf &color, const size_t unique_index, const mrpt::opengl::TOpenGLFont font)
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:41
mrpt::void_ptr_noncopy m_hwnd
The window handle.
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...
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...
void setCameraPointingToPoint(float x, float y, float z)
Changes the camera parameters programmatically.
mrptKeyModifier
Definition: keycodes.h:157
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:87
void OnMenuClose(wxCommandEvent &event)
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 wxBitmap getMRPTDefaultIcon()
GLAPI void GLAPIENTRY glReadBuffer(GLenum mode)
STL namespace.
CDisplayWindow3D * m_win3D
Definition: WxSubsystem.h:405
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
void setCameraProjective(bool isProjective)
Sets the camera as projective, or orthogonal.
float getCameraZoom() const
Get camera parameters programmatically.
void OnResize(wxSizeEvent &event)
int OPCODE
Valid codes are: For CDisplayWindow:
Definition: WxSubsystem.h:297
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 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
mrpt::img::CImage CImage
Definition: utils/CImage.h:5
const long ID_MENUITEM1
This base provides a set of functions for maths stuff.
#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: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
bool isOpen()
Returns false if the user has already closed the window.
A pair (x,y) of pixel coordinates (integer resolution).
Definition: TPixelCoord.h:37
std::shared_ptr< CDisplayWindow3D > Ptr
An event sent by a window upon a char pressed by the user.
const long ID_MENUITEM2
mrpt::gui::CDisplayWindow3D::Ptr win
GLsizei const GLchar ** string
Definition: glext.h:4101
mrptKeyModifier keyEventToMrptKeyModifier(const wxKeyEvent &ev)
Extracts the key modifiers from a wxKeyEvent.
Definition: WxUtils.cpp:1135
volatile mrptKeyModifier m_keyPushedModifier
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...
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:97
Definition: inftrees.h:28
void grabImagesStop()
Stops image grabbing started by grabImagesStart.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:16
GLuint id
Definition: glext.h:3909
A RGB color - floats in the range [0,1].
Definition: TColor.h:77
bool isCameraProjective() const
Sets the camera as projective, or orthogonal.
bool hasSubscribers() const
Can be called by a derived class before preparing an event for publishing with publishEvent to determ...
Definition: CObservable.h:53
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:48
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
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).
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
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:14
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.h:122
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:223
#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::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.
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:130
void setCameraElevationDeg(float deg)
Changes the camera parameters programmatically.
CMyGLCanvas_DisplayWindow3D * m_canvas
Definition: WxSubsystem.h:408
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.
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
Definition: common.h:186
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