Main MRPT website > C++ reference for MRPT 1.5.6
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 
31 
32 #if MRPT_HAS_OPENGL_GLUT
33  #ifdef MRPT_OS_WINDOWS
34  // Windows:
35  #include <windows.h>
36  #endif
37 
38  #ifdef MRPT_OS_APPLE
39  #include <OpenGL/gl.h>
40  #include <OpenGL/glu.h>
41  #include <GLUT/glut.h>
42  #else
43  #include <GL/gl.h>
44  #include <GL/glu.h>
45  #include <GL/glut.h>
46  #ifdef HAVE_FREEGLUT_EXT_H
47  #include <GL/freeglut_ext.h>
48  #endif
49  #endif
50 #endif
51 
52 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
53 
54 #if !wxUSE_GLCANVAS
55 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild wxWidgets"
56 #endif
57 
60 
61 namespace mrpt
62 {
63  namespace gui
64  {
65  class CMyGLCanvas_DisplayWindow3D : public mrpt::gui::CMyGLCanvasBase
66  {
67  public:
68  CMyGLCanvas_DisplayWindow3D( CDisplayWindow3D *win3D,
69  wxWindow *parent, wxWindowID id = wxID_ANY,
70  const wxPoint& pos = wxDefaultPosition,
71  const wxSize& size = wxDefaultSize,
72  long style = 0, const wxString& name = _T("CMyGLCanvas_DisplayWindow3D") );
73 
74  virtual ~CMyGLCanvas_DisplayWindow3D();
75 
76 
77  CDisplayWindow3D *m_win3D;
78 
79  // The idea is that CMyGLCanvas_DisplayWindow3D was derived from CTextMessageCapable, but
80  // that raises errors in MSVC when converting method pointers to wxObjectEventFunction...
81  struct THubClass : public mrpt::opengl::CTextMessageCapable
82  {
83  void render_text_messages_public(const int w, const int h) const { render_text_messages(w,h); }
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(CDisplayWindow3D *m_win3D, wxKeyEvent&ev);
96  };
97  }
98 }
99 
100 CMyGLCanvas_DisplayWindow3D::CMyGLCanvas_DisplayWindow3D(
101  CDisplayWindow3D *win3D,
102  wxWindow *parent, wxWindowID id,
103  const wxPoint& pos, const wxSize& size, long style, const wxString& name)
104  : CMyGLCanvasBase(parent,id,pos,size,style,name)
105 {
106  m_win3D = win3D;
107  Connect(wxEVT_CHAR,(wxObjectEventFunction)&CMyGLCanvas_DisplayWindow3D::OnCharCustom);
108  Connect(wxEVT_CHAR_HOOK,(wxObjectEventFunction)&CMyGLCanvas_DisplayWindow3D::OnCharCustom);
109 
110  Connect(wxEVT_LEFT_DOWN,(wxObjectEventFunction)&CMyGLCanvas_DisplayWindow3D::OnMouseDown);
111  Connect(wxEVT_RIGHT_DOWN,(wxObjectEventFunction)&CMyGLCanvas_DisplayWindow3D::OnMouseDown);
112  Connect(wxEVT_MOTION, (wxObjectEventFunction)&CMyGLCanvas_DisplayWindow3D::OnMouseMove);
113 }
114 
115 void CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(CDisplayWindow3D *m_win3D, wxKeyEvent&ev)
116 {
117  if (m_win3D)
118  {
119  if (ev.AltDown() && ev.GetKeyCode()== MRPTK_RETURN)
120  {
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 switching to fullscreen
132  // and the user is waiting for a key to close the window, a runtime crash will occur,
133  // so return now:
134  return;
135  }
136 
137  const int code = ev.GetKeyCode();
139 
140  m_win3D->m_keyPushedCode = code;
141  m_win3D->m_keyPushedModifier = mod;
142  m_win3D->m_keyPushed = true;
143 
144  // Send the event:
145  try {
146  m_win3D->publishEvent( mrptEventWindowChar(m_win3D,code,mod));
147  } catch(...) {}
148  }
149  //ev.Skip(); // Pass the event to whoever else.
150 }
151 
152 void CMyGLCanvas_DisplayWindow3D::OnCharCustom( wxKeyEvent& ev )
153 {
154  CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(m_win3D, ev);
155 }
156 
157 void CMyGLCanvas_DisplayWindow3D::OnMouseDown(wxMouseEvent& event)
158 {
159  // Send the event:
160  if (m_win3D && m_win3D->hasSubscribers())
161  {
162  try {
163  m_win3D->publishEvent( mrptEventMouseDown(m_win3D, TPixelCoord(event.GetX(), event.GetY()), event.LeftDown(), event.RightDown() ) );
164  } catch(...) { }
165  }
166 
167  event.Skip(); // so it's processed by the wx system!
168 }
169 
170 void CMyGLCanvas_DisplayWindow3D::OnMouseMove(wxMouseEvent& event)
171 {
172  // Send the event:
173  if (m_win3D && m_win3D->hasSubscribers())
174  {
175  try {
176  m_win3D->publishEvent(mrptEventMouseMove(m_win3D, TPixelCoord(event.GetX(), event.GetY()), event.LeftDown(), event.RightDown()));
177  }
178  catch (...) {}
179  }
180  event.Skip(); // so it's processed by the wx system!
181 }
182 
183 
184 CMyGLCanvas_DisplayWindow3D::~CMyGLCanvas_DisplayWindow3D()
185 {
186  m_openGLScene.clear_unique(); // Avoid the base class to free this object (it's freed by CDisplayWindow3D)
187 }
188 
189 void CMyGLCanvas_DisplayWindow3D::OnPreRender()
190 {
191  if (m_openGLScene) m_openGLScene.clear_unique();
192 
193  COpenGLScenePtr ptrScene = m_win3D->get3DSceneAndLock();
194  if (ptrScene)
195  m_openGLScene = ptrScene;
196 }
197 
198 void CMyGLCanvas_DisplayWindow3D::OnPostRender()
199 {
200  // Avoid the base class to free this object (it's freed by CDisplayWindow3D)
201  m_openGLScene.clear_unique();
202  m_win3D->unlockAccess3DScene();
203 
204  // If any, draw the 2D text messages:
205  int w,h;
206  this->GetSize(&w,&h);
207 
208  m_text_msgs.render_text_messages_public(w,h);
209 }
210 
211 void CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers(double At, wxPaintDC &dc)
212 {
213  if (m_win3D) m_win3D->internal_setRenderingFPS(At>0 ? 1.0/At : 1e9);
214 
215  // If we are requested to do so, grab images to disk as they are rendered:
216  string grabFile;
217  if (m_win3D)
218  grabFile = m_win3D->grabImageGetNextFile();
219  if (m_win3D && (!grabFile.empty() || m_win3D->isCapturingImgs()) )
220  {
221  int w,h;
222  dc.GetSize(&w, &h);
223 
224  //Save image directly from OpenGL - It could also use 4 channels and save with GL_BGRA_EXT
225  CImagePtr frame(new CImage(w, h, 3, false));
227  glReadPixels(0, 0, w, h, GL_BGR_EXT, GL_UNSIGNED_BYTE, (*frame)(0,0) );
228 
229  if (!grabFile.empty())
230  {
231  frame->saveToFile(grabFile);
232  m_win3D->internal_emitGrabImageEvent(grabFile);
233  }
234 
235  if (m_win3D->isCapturingImgs())
236  {
237  {
239  m_win3D->m_last_captured_img = frame;
240  frame.clear_unique();
241  }
242  }
243  }
244 }
245 
246 #endif // Wx + OpenGL
247 
248 #if MRPT_HAS_WXWIDGETS
249 
250 BEGIN_EVENT_TABLE(C3DWindowDialog,wxFrame)
251 
252 END_EVENT_TABLE()
253 
254 
255 const long C3DWindowDialog::ID_MENUITEM1 = wxNewId();
256 const long C3DWindowDialog::ID_MENUITEM2 = wxNewId();
257 
259  CDisplayWindow3D *win3D,
260  WxSubsystem::CWXMainFrame* parent,
261  wxWindowID id,
262  const std::string &caption,
263  wxSize initialSize ) :
264  m_win3D( win3D ),
265  m_mainFrame(parent)
266 {
267 #if MRPT_HAS_OPENGL_GLUT
268 
269  Create(parent, id, _U(caption.c_str()), wxDefaultPosition, initialSize, wxDEFAULT_FRAME_STYLE, _T("id"));
270 
271  wxIcon FrameIcon;
272  FrameIcon.CopyFromBitmap(mrpt::gui::WxSubsystem::getMRPTDefaultIcon());
273  SetIcon(FrameIcon);
274 
275  // Create the wxCanvas object:
276  m_canvas = new CMyGLCanvas_DisplayWindow3D( win3D, this, wxID_ANY, wxDefaultPosition, wxDefaultSize );
277 
278 
279  // Events:
280  Connect(wxID_ANY,wxEVT_CLOSE_WINDOW,(wxObjectEventFunction)&C3DWindowDialog::OnClose);
281  Connect(ID_MENUITEM1,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&C3DWindowDialog::OnMenuClose);
282  Connect(ID_MENUITEM2,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&C3DWindowDialog::OnMenuAbout);
283 
284  Connect(wxID_ANY,wxEVT_CHAR,(wxObjectEventFunction)&C3DWindowDialog::OnChar);
285 
286  Connect(wxID_ANY,wxEVT_SIZE,(wxObjectEventFunction)&C3DWindowDialog::OnResize);
287 
288  // Increment number of windows:
289  //int winCount =
291  //cout << "[C3DWindowDialog] Notifying new window: " << winCount << endl;
292 #else
293  THROW_EXCEPTION("MRPT was compiled without OpenGL support")
294 #endif
295  //this->Iconize(false);
296 }
297 
298 // Destructor
300 {
301 // cout << "[C3DWindowDialog::~C3DWindowDialog]" << endl;
302 }
303 
304 // OnClose event:
305 void C3DWindowDialog::OnClose(wxCloseEvent& event)
306 {
307  // Send the event:
308  bool allow_close=true;
309  try {
310  mrptEventWindowClosed ev(m_win3D, true /* allow close */);
311  m_win3D->publishEvent(ev);
312  allow_close = ev.allow_close;
313  } catch(...){}
314  if (!allow_close) return; // Don't process this close event.
315 
316  // cout << "[C3DWindowDialog::OnClose]" << endl;
317  // Set the m_hwnd=NULL in our parent object.
318  m_win3D->notifyChildWindowDestruction();
319 
320  // Decrement number of windows:
322 
323  // Signal we are destroyed:
324  m_win3D->m_semWindowDestroyed.release();
325 
326  event.Skip(); // keep processing by parent classes.
327 }
328 
329 // Menu: Close
330 void C3DWindowDialog::OnMenuClose(wxCommandEvent& event)
331 {
332  Close();
333 }
334 // Menu: About
335 void C3DWindowDialog::OnMenuAbout(wxCommandEvent& event)
336 {
337  ::wxMessageBox(_("3D Scene viewer\n Class gui::CDisplayWindow3D\n MRPT C++ library"),_("About..."));
338 }
339 
340 void C3DWindowDialog::OnChar(wxKeyEvent& ev)
341 {
342 #if MRPT_HAS_OPENGL_GLUT
343  CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(m_win3D, ev);
344 #endif
345 }
346 
347 void C3DWindowDialog::OnResize(wxSizeEvent& event)
348 {
349 #if MRPT_HAS_OPENGL_GLUT
350  // Send the event:
351  if (m_win3D)
352  {
353  try {
354  m_win3D->publishEvent( mrptEventWindowResize(m_win3D,event.GetSize().GetWidth(),event.GetSize().GetHeight()));
355  } catch(...) {}
356  }
357  event.Skip(); // so it's processed by the wx system!
358 #endif
359 }
360 
361 
363 {
364 #if MRPT_HAS_OPENGL_GLUT
365  m_canvas->m_text_msgs.clearTextMessages();
366 #endif
367 }
368 
370  const double x_frac,
371  const double y_frac,
372  const std::string &text,
374  const size_t unique_index,
375  const mrpt::opengl::TOpenGLFont font
376  )
377 {
378 #if MRPT_HAS_OPENGL_GLUT
379  m_canvas->m_text_msgs.addTextMessage( x_frac, y_frac, text,color,unique_index,font );
380 #endif
381 }
382 
384  const double x_frac,
385  const double y_frac,
386  const std::string &text,
388  const std::string &font_name,
389  const double font_size,
390  const mrpt::opengl::TOpenGLFontStyle font_style,
391  const size_t unique_index,
392  const double font_spacing,
393  const double font_kerning,
394  const bool has_shadow,
395  const mrpt::utils::TColorf &shadow_color
396  )
397 {
398 #if MRPT_HAS_OPENGL_GLUT
399  m_canvas->m_text_msgs.addTextMessage( x_frac, y_frac, text,color, font_name, font_size, font_style, unique_index, font_spacing, font_kerning,has_shadow,shadow_color );
400 #endif
401 }
402 
403 
404 
405 #endif // MRPT_HAS_WXWIDGETS
406 
407 /*---------------------------------------------------------------
408  Constructor
409  ---------------------------------------------------------------*/
411  const std::string &windowCaption,
412  unsigned int initialWindowWidth,
413  unsigned int initialWindowHeight )
414  : CBaseGUIWindow(static_cast<void*>(this),300,399, windowCaption),
415  m_csAccess3DScene(),
416  m_grab_imgs_prefix(),
417  m_grab_imgs_idx(0),
418  m_is_capturing_imgs(false),
419  m_last_captured_img_cs("m_last_captured_img_cs"),
420  m_lastFullScreen (mrpt::system::now()),
421  m_last_FPS(10)
422 {
423 // static mrpt::utils::CStdOutStream oo;
424 // m_csAccess3DScene.m_debugOut = &oo;
425 
426  m_3Dscene = COpenGLScene::Create();
427  CBaseGUIWindow::createWxWindow(initialWindowWidth,initialWindowHeight);
428 }
429 
430 CDisplayWindow3DPtr CDisplayWindow3D::Create(
431  const std::string &windowCaption,
432  unsigned int initialWindowWidth,
433  unsigned int initialWindowHeight )
434 {
435  return CDisplayWindow3DPtr(new CDisplayWindow3D(windowCaption,initialWindowWidth,initialWindowHeight));
436 }
437 /*---------------------------------------------------------------
438  Destructor
439  ---------------------------------------------------------------*/
441 {
442  // get lock so we make sure nobody else is touching the window right now.
445 
447 }
448 
449 
450 /*---------------------------------------------------------------
451  resize
452  ---------------------------------------------------------------*/
454  unsigned int width,
455  unsigned int height )
456 {
457 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
458  if (!isOpen())
459  {
460  cerr << "[CDisplayWindow3D::setPos] Window closed!: " << m_caption << endl;
461  return;
462  }
463 
464  // Send a request to destroy this object:
466  REQ->source3D = this;
467  REQ->OPCODE = 303;
468  REQ->x = width;
469  REQ->y = height;
471 #else
472  MRPT_UNUSED_PARAM(width);
473  MRPT_UNUSED_PARAM(height);
474 #endif
475 }
476 
477 /*---------------------------------------------------------------
478  setPos
479  ---------------------------------------------------------------*/
480 void CDisplayWindow3D::setPos( int x, int y )
481 {
482 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
483  if (!isOpen())
484  {
485  cerr << "[CDisplayWindow3D::setPos] Window closed!: " << m_caption << endl;
486  return;
487  }
488 
489  // Send a request to destroy this object:
491  REQ->source3D = this;
492  REQ->OPCODE = 302;
493  REQ->x = x;
494  REQ->y = y;
496 #else
498 #endif
499 }
500 
501 /*---------------------------------------------------------------
502  setWindowTitle
503  ---------------------------------------------------------------*/
505 {
506 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
507  if (!isOpen())
508  {
509  cerr << "[CDisplayWindow3D::setWindowTitle] Window closed!: " << m_caption << endl;
510  return;
511  }
512 
513  // Send a request to destroy this object:
515  REQ->source3D = this;
516  REQ->OPCODE = 304;
517  REQ->str = str;
519 #else
520  MRPT_UNUSED_PARAM(str);
521 #endif
522 }
523 
524 
525 /*---------------------------------------------------------------
526  get3DSceneAndLock
527  ---------------------------------------------------------------*/
528 opengl::COpenGLScenePtr& CDisplayWindow3D::get3DSceneAndLock( )
529 {
531  return m_3Dscene;
532 }
533 
534 /*---------------------------------------------------------------
535  unlockAccess3DScene
536  ---------------------------------------------------------------*/
538 {
540 }
541 
542 /*---------------------------------------------------------------
543  forceRepaint
544  ---------------------------------------------------------------*/
546 {
547 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
549  if (win)
550  {
551  //win->Refresh(false); // Do not erase background
552  // We must do this from the wx thread!
553 
554  // Send refresh request:
556  REQ->source3D = this;
557  REQ->OPCODE = 350;
559  }
560 #endif
561 }
562 
563 /*---------------------------------------------------------------
564  setCameraElevationDeg
565  ---------------------------------------------------------------*/
567 {
568 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
570  if (win)
571  win->m_canvas->cameraElevationDeg = deg;
572 #else
573  MRPT_UNUSED_PARAM(deg);
574 #endif
575 }
576 
578 {
579 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
581  if (win)
582  win->m_canvas->useCameraFromScene = useIt;
583 #else
584  MRPT_UNUSED_PARAM(useIt);
585 #endif
586 }
587 
588 /*---------------------------------------------------------------
589  setCameraAzimuthDeg
590  ---------------------------------------------------------------*/
592 {
593 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
595  if (win)
596  win->m_canvas->cameraAzimuthDeg = deg;
597 #else
598  MRPT_UNUSED_PARAM(deg);
599 #endif
600 }
601 
602 /*---------------------------------------------------------------
603  setCameraPointingToPoint
604  ---------------------------------------------------------------*/
606 {
607 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
609  if (win)
610  {
611  win->m_canvas->cameraPointingX = x;
612  win->m_canvas->cameraPointingY = y;
613  win->m_canvas->cameraPointingZ = z;
614  }
615 #else
617 #endif
618 }
619 
620 /*---------------------------------------------------------------
621  setCameraZoom
622  ---------------------------------------------------------------*/
624 {
625 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
627  if (win)
628  win->m_canvas->cameraZoomDistance = zoom;
629 #else
630  MRPT_UNUSED_PARAM(zoom);
631 #endif
632 }
633 
634 /*---------------------------------------------------------------
635  setCameraProjective
636  ---------------------------------------------------------------*/
637 void CDisplayWindow3D::setCameraProjective( bool isProjective )
638 {
639 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
641  if (win)
642  win->m_canvas->cameraIsProjective = isProjective;
643 #else
644  MRPT_UNUSED_PARAM(isProjective);
645 #endif
646 }
647 
648 void CDisplayWindow3D::setMinRange(double new_min)
649 {
650  if (m_3Dscene)
651  {
652  mrpt::opengl::COpenGLViewportPtr gl_view = m_3Dscene->getViewport("main");
653  if (gl_view)
654  {
655  double m,M;
656  gl_view->getViewportClipDistances(m,M);
657  gl_view->setViewportClipDistances(new_min,M);
658  }
659  }
660 }
661 void CDisplayWindow3D::setMaxRange(double new_max)
662 {
663  if (m_3Dscene)
664  {
665  mrpt::opengl::COpenGLViewportPtr gl_view = m_3Dscene->getViewport("main");
666  if (gl_view)
667  {
668  double m,M;
669  gl_view->getViewportClipDistances(m,M);
670  gl_view->setViewportClipDistances(m,new_max);
671  }
672  }
673 }
674 
676 {
677 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
679  if (win)
680  return win->m_canvas->cameraFOV;
681 #endif
682  return .0f;
683 }
684 
686 {
687 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
689  if (win)
690  win->m_canvas->cameraFOV = v;
691 #endif
692 }
693 
694 /*---------------------------------------------------------------
695  getCameraElevationDeg
696  ---------------------------------------------------------------*/
698 {
699 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
700  const C3DWindowDialog *win = (const C3DWindowDialog*) m_hwnd.get();
701  return win ? win->m_canvas->cameraElevationDeg : 0;
702 #else
703  return 0;
704 #endif
705 }
706 
707 /*---------------------------------------------------------------
708  getCameraAzimuthDeg
709  ---------------------------------------------------------------*/
711 {
712 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
713  const C3DWindowDialog *win = (const C3DWindowDialog*) m_hwnd.get();
714  return win ? win->m_canvas->cameraAzimuthDeg : 0;
715 #else
716  return 0;
717 #endif
718 }
719 
720 /*---------------------------------------------------------------
721  getCameraPointingToPoint
722  ---------------------------------------------------------------*/
723 void CDisplayWindow3D::getCameraPointingToPoint( float &x,float &y, float &z ) const
724 {
725 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
726  const C3DWindowDialog *win = (const C3DWindowDialog*) m_hwnd.get();
727  if (win)
728  {
729  x = win->m_canvas->cameraPointingX;
730  y = win->m_canvas->cameraPointingY;
731  z = win->m_canvas->cameraPointingZ;
732  }
733  else
734  x=y=z=0;
735 #else
737 #endif
738 }
739 
740 /*---------------------------------------------------------------
741  getCameraZoom
742  ---------------------------------------------------------------*/
744 {
745 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
746  const C3DWindowDialog *win = (const C3DWindowDialog*) m_hwnd.get();
747  return win ? win->m_canvas->cameraZoomDistance : 0;
748 #else
749  return 0;
750 #endif
751 }
752 
753 /*---------------------------------------------------------------
754  isCameraProjective
755  ---------------------------------------------------------------*/
757 {
758 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
759  const C3DWindowDialog *win = (const C3DWindowDialog*) m_hwnd.get();
760  return win ? win->m_canvas->cameraIsProjective : true;
761 #else
762  return true;
763 #endif
764 }
765 
766 /*---------------------------------------------------------------
767  getLastMousePosition
768  ---------------------------------------------------------------*/
770 {
771 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
772  const C3DWindowDialog *win = (const C3DWindowDialog*) m_hwnd.get();
773  if (!win) return false;
774  win->m_canvas->getLastMousePosition(x,y);
775  return true;
776 #else
778  return false;
779 #endif
780 }
781 
782 /*---------------------------------------------------------------
783  getLastMousePositionRay
784  ---------------------------------------------------------------*/
786 {
787  int x,y;
788  if (getLastMousePosition(x,y))
789  {
791  m_3Dscene->getViewport("main")->get3DRayForPixelCoord(x,y,ray);
793  return true;
794  }
795  else return false;
796 }
797 
798 
799 /*---------------------------------------------------------------
800  setCursorCross
801  ---------------------------------------------------------------*/
802 void CDisplayWindow3D::setCursorCross(bool cursorIsCross)
803 {
804 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
805  const C3DWindowDialog *win = (const C3DWindowDialog*) m_hwnd.get();
806  if (!win) return;
807  win->m_canvas->SetCursor( *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR) );
808 #else
809  MRPT_UNUSED_PARAM(cursorIsCross);
810 #endif
811 }
812 
813 
814 /*---------------------------------------------------------------
815  grabImagesStart
816  ---------------------------------------------------------------*/
817 void CDisplayWindow3D::grabImagesStart( const std::string &grab_imgs_prefix )
818 {
819  m_grab_imgs_prefix = grab_imgs_prefix;
820  m_grab_imgs_idx = 0;
821 }
822 
823 /*---------------------------------------------------------------
824  grabImagesStop
825  ---------------------------------------------------------------*/
827 {
828  m_grab_imgs_prefix.clear();
829 }
830 
831 /*---------------------------------------------------------------
832  grabImageGetNextFile
833  ---------------------------------------------------------------*/
835 {
836  if ( m_grab_imgs_prefix.empty() )
837  return string();
838  else return format( "%s%06u.png",m_grab_imgs_prefix.c_str(), m_grab_imgs_idx++ );
839 }
840 
841 
842 /*---------------------------------------------------------------
843  captureImagesStart
844  ---------------------------------------------------------------*/
846 {
847  m_is_capturing_imgs = true;
848 }
849 
850 /*---------------------------------------------------------------
851  captureImagesStop
852  ---------------------------------------------------------------*/
854 {
855  m_is_capturing_imgs = false;
856 }
857 
858 /*---------------------------------------------------------------
859  getLastWindowImage
860  ---------------------------------------------------------------*/
862 {
863  bool ret;
864 
865  {
868  {
869  out_img = *m_last_captured_img; // Copy the full image
870  ret = true;
871  }
872  else ret = false;
873  }
874  return ret;
875 }
876 
877 /*---------------------------------------------------------------
878  getLastWindowImagePtr
879  ---------------------------------------------------------------*/
881 {
883  return m_last_captured_img;
884 }
885 
886 /*---------------------------------------------------------------
887  addTextMessage
888  ---------------------------------------------------------------*/
890  const double x_frac,
891  const double y_frac,
892  const std::string &text,
894  const size_t unique_index,
895  const TOpenGLFont font
896  )
897 {
898 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
900  if (win)
901  {
902  // Send request:
903  // Add a 2D text message:
904  // vector_x: [0]:x, [1]:y, [2,3,4]:R G B, "x": enum of desired font. "y": unique index, "str": String.
906  REQ->source3D = this;
907  REQ->OPCODE = 360;
908  REQ->str = text;
909  REQ->vector_x.resize(5);
910  REQ->vector_x[0] = x_frac;
911  REQ->vector_x[1] = y_frac;
912  REQ->vector_x[2] = color.R;
913  REQ->vector_x[3] = color.G;
914  REQ->vector_x[4] = color.B;
915  REQ->x = int(font);
916  REQ->y = int(unique_index);
917 
919  }
920 #else
921  MRPT_UNUSED_PARAM(x_frac); MRPT_UNUSED_PARAM(y_frac); MRPT_UNUSED_PARAM(text);
922  MRPT_UNUSED_PARAM(color); MRPT_UNUSED_PARAM(unique_index); MRPT_UNUSED_PARAM(font);
923 #endif
924 }
925 
926 /*---------------------------------------------------------------
927  addTextMessage
928  ---------------------------------------------------------------*/
930  const double x_frac,
931  const double y_frac,
932  const std::string &text,
934  const std::string &font_name,
935  const double font_size,
936  const mrpt::opengl::TOpenGLFontStyle font_style,
937  const size_t unique_index,
938  const double font_spacing,
939  const double font_kerning,
940  const bool draw_shadow,
941  const mrpt::utils::TColorf &shadow_color
942  )
943 {
944 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
946  if (win)
947  {
948  // Send request:
949  // Add a 2D text message:
951  REQ->source3D = this;
952  REQ->OPCODE = 362;
953  REQ->str = text;
954  REQ->plotName = font_name;
955  REQ->vector_x.resize(12);
956  REQ->vector_x[0] = x_frac;
957  REQ->vector_x[1] = y_frac;
958  REQ->vector_x[2] = color.R;
959  REQ->vector_x[3] = color.G;
960  REQ->vector_x[4] = color.B;
961  REQ->vector_x[5] = font_size;
962  REQ->vector_x[6] = font_spacing;
963  REQ->vector_x[7] = font_kerning;
964  REQ->vector_x[8] = draw_shadow ? 1:0;
965  REQ->vector_x[9] = shadow_color.R;
966  REQ->vector_x[10] = shadow_color.G;
967  REQ->vector_x[11] = shadow_color.B;
968 
969  REQ->x = int(font_style);
970  REQ->y = int(unique_index);
971 
973  }
974 #else
975  MRPT_UNUSED_PARAM(x_frac);
976  MRPT_UNUSED_PARAM(y_frac);
977  MRPT_UNUSED_PARAM(text);
978  MRPT_UNUSED_PARAM(color);
979  MRPT_UNUSED_PARAM(font_name);
980  MRPT_UNUSED_PARAM(font_size);
981  MRPT_UNUSED_PARAM(font_style);
982  MRPT_UNUSED_PARAM(unique_index);
983  MRPT_UNUSED_PARAM(font_spacing);
984  MRPT_UNUSED_PARAM(font_kerning);
985  MRPT_UNUSED_PARAM(draw_shadow);
986  MRPT_UNUSED_PARAM(shadow_color);
987 #endif
988 }
989 
990 /*---------------------------------------------------------------
991  clearTextMessages
992  ---------------------------------------------------------------*/
994 {
995 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
997  if (win)
998  {
999  // 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.
1022 mrpt::opengl::COpenGLViewportPtr CDisplayWindow3D::getDefaultViewport()
1023 {
1025  mrpt::opengl::COpenGLViewportPtr view = m_3Dscene->getViewport("main");
1027  return view;
1028 }
1029 
1031 {
1033  mrpt::opengl::COpenGLViewportPtr view = m_3Dscene->getViewport("main");
1034  view->setImageView(img);
1036 }
1037 
1039 {
1041  mrpt::opengl::COpenGLViewportPtr view = m_3Dscene->getViewport("main");
1042  view->setImageView_fast(img);
1044 }
1045 
1046 
1047 CDisplayWindow3DLocker::CDisplayWindow3DLocker(CDisplayWindow3D &win, mrpt::opengl::COpenGLScenePtr &out_scene_ptr) :
1048  m_win(win)
1049 {
1050  out_scene_ptr = m_win.get3DSceneAndLock();
1051 }
1053  m_win(win)
1054 {
1056 }
1058 {
1060 }
1061 
void getCameraPointingToPoint(float &x, float &y, float &z) const
Get camera parameters programmatically.
An event sent by a window upon resize.
virtual ~CDisplayWindow3D()
Destructor.
const GLdouble * v
Definition: glew.h:1296
mrpt::utils::CImagePtr m_last_captured_img
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...
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1166
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)
A class acquiring a CCriticalSection at its constructor, and releasing it at destructor.
An event sent by a window upon a mouse click, giving the (x,y) pixel coordinates. ...
mrpt::opengl::COpenGLScenePtr m_3Dscene
Internal OpenGL object (see general discussion in about usage of this object)
void enter() const MRPT_OVERRIDE
Enter. the calling thread already possesses this critical section (it would be a dead-lock).
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:49
GLvoid *typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1745
void OnClose(wxCloseEvent &event)
mrpt::gui::CDisplayWindow3D * source3D
Only one of source* can be non-NULL, indicating the class that generated the request.
Definition: WxSubsystem.h:200
The data structure for each inter-thread request:
Definition: WxSubsystem.h:182
#define _U(x)
Definition: WxSubsystem.h:470
#define IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace)
This must be inserted in all CObject classes implementation files.
Definition: CObject.h:256
std::string m_caption
The caption of the window.
mrpt::opengl::COpenGLViewportPtr getDefaultViewport()
A short cut for getting the "main" viewport of the scene object, it is equivalent to: ...
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:101
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.
CDisplayWindow3DLocker(CDisplayWindow3D &win, mrpt::opengl::COpenGLScenePtr &out_scene_ptr)
Acquires the lock of the 3D scene of the referenced window, and returns a copy of the smart pointer t...
virtual bool getLastMousePosition(int &x, int &y) const MRPT_OVERRIDE
Gets the last x,y pixel coordinates of the mouse.
Keeps a list of text messages which can be rendered to OpenGL contexts by graphic classes...
#define THROW_EXCEPTION(msg)
float getCameraElevationDeg() const
Get camera parameters programmatically.
A pair (x,y) of pixel coordinates (integer resolution).
Definition: TPixelCoord.h:37
void setCameraPointingToPoint(float x, float y, float z)
Changes the camera parameters programmatically.
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1797
mrptKeyModifier
Definition: keycodes.h:158
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:70
void OnMenuClose(wxCommandEvent &event)
mrpt::utils::CImagePtr getLastWindowImagePtr() const
Retrieve the last captured image from the window, as a smart pointer.
static wxBitmap getMRPTDefaultIcon()
GLAPI void GLAPIENTRY glReadBuffer(GLenum mode)
#define GL_UNSIGNED_BYTE
Definition: glew.h:298
void internal_emitGrabImageEvent(const std::string &fil)
called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers
void setCameraProjective(bool isProjective)
Sets the camera as projective, or orthogonal.
void setImageView_fast(mrpt::utils::CImage &img)
Just like setImageView but moves the internal image memory instead of making a copy, so it's faster but empties the input image.
void OnResize(wxSizeEvent &event)
int OPCODE
Valid codes are: For CDisplayWindow:
Definition: WxSubsystem.h:259
mrpt::synch::CCriticalSectionRecursive m_csAccess3DScene
Critical section for accesing m_3Dscene.
An event sent by a window upon when it's about to be closed, either manually by the user or programat...
An event sent by a window when the mouse is moved over it.
void OnChar(wxKeyEvent &event)
bool hasSubscribers() const
Can be called by a derived class before preparing an event for publishing with publishEvent to determ...
Definition: CObservable.h:52
void setImageView(const mrpt::utils::CImage &img)
Set the "main" viewport into "image view"-mode, where an image is efficiently drawn (fitting the view...
bool isCameraProjective() const
Sets the camera as projective, or orthogonal.
void notifyChildWindowDestruction()
Called by wx main thread to set m_hwnd to NULL.
GLint GLvoid * img
Definition: glew.h:1290
mrpt::opengl::COpenGLScenePtr & get3DSceneAndLock()
Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introductio...
const long ID_MENUITEM1
#define GL_BGR_EXT
Definition: glew.h:4693
static CDisplayWindow3DPtr Create()
TOpenGLFont
Existing fonts for 2D texts in mrpt::opengl methods.
Definition: opengl_fonts.h:26
void setMaxRange(double new_max)
Changes the camera max clip range (z) (used for gluPerspective. The window is not updated with this m...
#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)
std::string grabImageGetNextFile()
Increments by one the image counter and return the next image file name (Users normally don't want to...
TOpenGLFontStyle
Different style for vectorized font rendering.
Definition: opengl_fonts.h:37
bool isOpen()
Returns false if the user has already closed the window.
GLint GLint GLint GLint GLint x
Definition: glew.h:1166
virtual void setCursorCross(bool cursorIsCross) MRPT_OVERRIDE
Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) ...
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
void release(unsigned int increaseCount=1)
Increments the count of the semaphore by a given amount.
GLuint const GLchar * name
Definition: glew.h:1721
void setPos(int x, int y) MRPT_OVERRIDE
Changes the position of the window on the screen.
An event sent by a window upon a char pressed by the user.
const long ID_MENUITEM2
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
GLuint color
Definition: glew.h:5778
mrptKeyModifier keyEventToMrptKeyModifier(const wxKeyEvent &ev)
Extracts the key modifiers from a wxKeyEvent.
Definition: WxUtils.cpp:944
bool getLastWindowImage(mrpt::utils::CImage &out_img) const
Retrieve the last captured image from the window.
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
Definition: glew.h:1166
volatile mrptKeyModifier m_keyPushedModifier
void forceRepaint()
Repaints the window. forceRepaint, repaint and updateWindow are all aliases of the same method...
float getCameraAzimuthDeg() const
Get camera parameters programmatically.
GLsizeiptr size
Definition: glew.h:1586
void setWindowTitle(const std::string &str) MRPT_OVERRIDE
Changes the window title.
GLdouble GLdouble z
Definition: glew.h:1464
mrpt::system::TTimeStamp m_lastFullScreen
This class implements the GUI thread required for the wxWidgets-based GUI.
Definition: WxSubsystem.h:99
GLsizei const GLcharARB ** string
Definition: glew.h:3293
Definition: inftrees.h:28
synch::CCriticalSection m_last_captured_img_cs
void grabImagesStop()
Stops image grabbing started by grabImagesStart.
synch::CSemaphore m_semWindowDestroyed
This semaphore will be signaled when the wx window is destroyed.
void setCameraZoom(float zoom)
Changes the 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. ...
A RGB color - floats in the range [0,1].
Definition: TColor.h:80
void destroyWxWindow()
Must be called by child classes in their destructors. The code cannot be put into this class' destruc...
void setMinRange(double new_min)
Changes the camera min clip range (z) (used for gluPerspective). The window is not updated with this ...
const GLdouble * m
Definition: glew.h:5094
float getCameraZoom() const
Get camera parameters programmatically.
void createWxWindow(unsigned int initialWidth, unsigned int initialHeight)
Must be called by child classes just within the constructor.
void captureImagesStop()
Stop image grabbing.
CDisplayWindow3D(const std::string &windowCaption=std::string(), unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Constructor.
double BASE_IMPEXP 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:205
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1166
std::string str
Parameters, depending on OPCODE.
Definition: WxSubsystem.h:210
#define GL_FRONT
Definition: glew.h:313
void internal_setRenderingFPS(double FPS)
Set the rendering FPS (users don't call this, the method is for internal MRPT objects only) ...
void clearTextMessages()
Clear all text messages created with addTextMessage().
void resize(unsigned int width, unsigned int height) MRPT_OVERRIDE
Resizes the window, stretching the image to fit into the display area.
mrpt::utils::void_ptr_noncopy m_hwnd
The window handle.
void leave() const MRPT_OVERRIDE
Leave. the calling thread is not the current owner of the critical section.
The base class for GUI window classes.
void setFOV(float v)
Changes the camera field of view (in degrees) (used for gluPerspective). The window is not updated wi...
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.
float getFOV() const
Return the camera field of view (in degrees) (used for gluPerspective)
CMyGLCanvas_DisplayWindow3D * m_canvas
Definition: WxSubsystem.h:361
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.



Page generated by Doxygen 1.8.6 for MRPT 1.5.6 Git: 4c65e84 Tue Apr 24 08:18:17 2018 +0200 at mar abr 24 08:26:17 CEST 2018