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