MRPT  2.0.3
CWxGLCanvasBase.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "gui-precomp.h" // Precompiled headers
11 
13 #include <mrpt/gui/WxSubsystem.h>
14 #include <mrpt/system/CTicTac.h>
15 
16 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
17 
18 #if MRPT_HAS_OPENGL_GLUT
19 #ifdef _WIN32
20 // Windows:
21 #include <windows.h>
22 #endif
23 
24 #ifdef __APPLE__
25 #include <GLUT/glut.h>
26 #include <OpenGL/gl.h>
27 #include <OpenGL/glu.h>
28 #else
29 #include <GL/gl.h>
30 #include <GL/glu.h>
31 #include <GL/glut.h>
32 #ifdef HAVE_FREEGLUT_EXT_H
33 #include <GL/freeglut_ext.h>
34 #endif
35 #endif
36 
37 #endif
38 
39 #if !wxUSE_GLCANVAS
40 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild wxWidgets"
41 #endif
42 
43 using namespace mrpt;
44 using namespace mrpt::gui;
45 using namespace mrpt::opengl;
46 using namespace std;
47 
48 /*----------------------------------------------------------------
49  Implementation of Test-GLCanvas
50 -----------------------------------------------------------------*/
51 
52 void CWxGLCanvasBase::OnWindowCreation(wxWindowCreateEvent& ev)
53 {
54  if (!m_gl_context) m_gl_context = std::make_unique<wxGLContext>(this);
55 }
56 
57 void CWxGLCanvasBase::swapBuffers()
58 {
59  if (m_gl_context)
60  {
61  SetCurrent(*m_gl_context);
62  SwapBuffers();
63  }
64 }
65 void CWxGLCanvasBase::preRender() { OnPreRender(); }
66 void CWxGLCanvasBase::postRender() { OnPostRender(); }
67 void CWxGLCanvasBase::renderError(const string& err_msg)
68 {
69  OnRenderError(err_msg.c_str());
70 }
71 
72 void CWxGLCanvasBase::OnMouseDown(wxMouseEvent& event)
73 {
74  setMousePos(event.GetX(), event.GetY());
75  setMouseClicked(true);
76 }
77 void CWxGLCanvasBase::OnMouseUp(wxMouseEvent& /*event*/)
78 {
79  setMouseClicked(false);
80 }
81 
82 void CWxGLCanvasBase::OnMouseMove(wxMouseEvent& event)
83 {
84  bool leftIsDown = event.LeftIsDown();
85 
86  int X = event.GetX();
87  int Y = event.GetY();
88  updateLastPos(X, Y);
89 
90  if (leftIsDown || event.RightIsDown())
91  {
92  // Proxy variables to cache the changes:
93  CamaraParams params = cameraParams();
94 
95  if (leftIsDown)
96  {
97  if (event.ShiftDown())
98  updateZoom(params, X, Y);
99 
100  else if (event.ControlDown())
101  updateRotate(params, X, Y);
102 
103  else
104  updateOrbitCamera(params, X, Y);
105  }
106  else
107  updatePan(params, X, Y);
108 
109  setMousePos(X, Y);
110  setCameraParams(params);
111 
112 #if wxCHECK_VERSION(2, 9, 5)
113  wxTheApp->SafeYieldFor(nullptr, wxEVT_CATEGORY_TIMER);
114 #endif
115 
116  Refresh();
117  Update();
118  }
119 
120  // ensure we have the focus so we get keyboard events:
121  this->SetFocus();
122 }
123 
124 void CWxGLCanvasBase::OnMouseWheel(wxMouseEvent& event)
125 {
126  CamaraParams params = cameraParams();
127  updateZoom(params, event.GetWheelRotation());
128  setCameraParams(params);
129 
130  Refresh(false);
131  // ensure we have the focus so we get keyboard events:
132  this->SetFocus();
133 }
134 
135 // clang-format off
136 static int WX_GL_ATTR_LIST[] = {
137  WX_GL_DOUBLEBUFFER, WX_GL_RGBA,
138  WX_GL_DEPTH_SIZE, 24,
139 #if wxCHECK_VERSION(3, 0, 3)
140  WX_GL_MAJOR_VERSION, 3,
141  WX_GL_MINOR_VERSION, 1,
142  WX_GL_CORE_PROFILE, // do not allow using opengl 1.x deprecated stuff
143 #endif
144  0
145 };
146 // clang-format on
147 
148 CWxGLCanvasBase::CWxGLCanvasBase(
149  wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
150  long style, const wxString& name)
151  : CGlCanvasBase(),
152  wxGLCanvas(
153  parent, id, WX_GL_ATTR_LIST, pos, size,
154  style | wxFULL_REPAINT_ON_RESIZE, name)
155 {
156  this->Bind(wxEVT_LEFT_DOWN, &CWxGLCanvasBase::OnMouseDown, this);
157  this->Bind(wxEVT_RIGHT_DOWN, &CWxGLCanvasBase::OnMouseDown, this);
158  this->Bind(wxEVT_LEFT_UP, &CWxGLCanvasBase::OnMouseUp, this);
159  this->Bind(wxEVT_RIGHT_UP, &CWxGLCanvasBase::OnMouseUp, this);
160  this->Bind(wxEVT_MOTION, &CWxGLCanvasBase::OnMouseMove, this);
161  this->Bind(wxEVT_MOUSEWHEEL, &CWxGLCanvasBase::OnMouseWheel, this);
162  this->Bind(wxEVT_CHAR, &CWxGLCanvasBase::OnChar, this);
163  this->Bind(wxEVT_CHAR_HOOK, &CWxGLCanvasBase::OnChar, this);
164  this->Bind(wxEVT_CREATE, &CWxGLCanvasBase::OnWindowCreation, this);
165 
166  this->Bind(wxEVT_SIZE, &CWxGLCanvasBase::OnSize, this);
167  this->Bind(wxEVT_PAINT, &CWxGLCanvasBase::OnPaint, this);
168  this->Bind(
169  wxEVT_ERASE_BACKGROUND, &CWxGLCanvasBase::OnEraseBackground, this);
170  this->Bind(wxEVT_ENTER_WINDOW, &CWxGLCanvasBase::OnEnterWindow, this);
171 
172 // JL: There seems to be a problem in MSW we don't receive this event, but
173 // in GTK we do and at the right moment to avoid an X server crash.
174 #ifdef _WIN32
175  wxWindowCreateEvent dum;
176  OnWindowCreation(dum);
177 #endif
178 }
179 
180 void CWxGLCanvasBase::OnChar(wxKeyEvent& event) { OnCharCustom(event); }
181 void CWxGLCanvasBase::Render()
182 {
183  wxPaintDC dc(this);
184 
185  if (!m_gl_context)
186  { /*cerr << "[CWxGLCanvasBase::Render] No GL Context!" << endl;*/
187  return;
188  }
189  else
190  SetCurrent(*m_gl_context);
191 
192  // Init OpenGL once, but after SetCurrent
193  if (!m_init)
194  {
195  InitGL();
196  m_init = true;
197  }
198 
199  int width, height;
200  GetClientSize(&width, &height);
201  double At = renderCanvas(width, height);
202 
203  OnPostRenderSwapBuffers(At, dc);
204 }
205 
206 void CWxGLCanvasBase::OnEnterWindow(wxMouseEvent& WXUNUSED(event))
207 {
208  SetFocus();
209 }
210 
211 void CWxGLCanvasBase::OnPaint(wxPaintEvent& WXUNUSED(event)) { Render(); }
212 void CWxGLCanvasBase::OnSize(wxSizeEvent& event)
213 {
214  if (!m_parent->IsShown()) return;
215 
216  // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
217  int w, h;
218  GetClientSize(&w, &h);
219 
220  if (this->IsShownOnScreen())
221  {
222  if (!m_gl_context)
223  { /*cerr << "[CWxGLCanvasBase::Render] No GL Context!" << endl;*/
224  return;
225  }
226  else
227  SetCurrent(*m_gl_context);
228 
229  resizeViewport(w, h);
230  }
231 }
232 
233 void CWxGLCanvasBase::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
234 {
235  // Do nothing, to avoid flashing.
236 }
237 
238 void CWxGLCanvasBase::InitGL()
239 {
240  if (!m_gl_context)
241  { /*cerr << "[CWxGLCanvasBase::Render] No GL Context!" << endl;*/
242  return;
243  }
244  else
245  SetCurrent(*m_gl_context);
246 
247  static bool GLUT_INIT_DONE = false;
248 
249  if (!GLUT_INIT_DONE)
250  {
251  GLUT_INIT_DONE = true;
252 
253  int argc = 1;
254  char* argv[1] = {nullptr};
255  glutInit(&argc, argv);
256  }
257 }
258 
259 void CWxGLCanvasBase::setCameraPose(const mrpt::poses::CPose3D& camPose)
260 {
261  THROW_EXCEPTION("todo");
262 }
263 
264 #endif // MRPT_HAS_WXWIDGETS
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
size_t size(const MATRIXLIKE &m, const int dim)
mrpt::vision::TStereoCalibParams params
STL namespace.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
const char * argv[]
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:85
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:13
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:14
const int argc
This base class implements a working with opengl::Camera and a OpenGL canvas, and it&#39;s used in gui::C...
Definition: CGlCanvasBase.h:24



Page generated by Doxygen 1.8.14 for MRPT 2.0.3 Git: 8e9e8af54 Wed May 13 17:41:24 2020 +0200 at miƩ may 13 17:55:54 CEST 2020